Initial commit
This commit is contained in:
commit
1f8ac5117c
188 changed files with 17272 additions and 0 deletions
4
.aiexclude
Normal file
4
.aiexclude
Normal 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
6
.claude/settings.json
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
||||||
|
"permissions": {
|
||||||
|
"deny": []
|
||||||
|
}
|
||||||
|
}
|
||||||
4
.clineignore
Normal file
4
.clineignore
Normal 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
55
.clinerules
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
# 공통 규칙
|
||||||
|
|
||||||
|
**현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
|
||||||
|
|
||||||
|
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
|
||||||
|
- `agent-ops/rules/common/**`와 `agent-ops/skills/common/**`은 중앙 관리되는 공통 영역이므로 어떤 프로젝트 작업에서도 사용자가 직접 지시하지 않는 이상 절대 직접 수정하지 않는다. 프로젝트별 규칙과 스킬은 반드시 대응하는 `project/**` 영역에만 반영한다.
|
||||||
|
- 최종 답변은 한국어로 한다.
|
||||||
|
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
|
||||||
|
- 요청 범위를 넘는 변경을 하지 않는다.
|
||||||
|
- 불확실하면 단정하지 말고 후보를 제시한다.
|
||||||
|
- `agent-task/archive/**`는 일반 작업에서 읽지 않는다. 예외: 사용자가 과거 작업 확인, 복원, 비교, 특정 archive 경로 확인을 요청한 경우, active `PLAN-*.md` / `CODE_REVIEW-*.md` / `USER_REVIEW.md`가 특정 archive evidence 경로를 명시한 경우, 또는 plan/code-review 루프의 split subtask 선행 의존성 충족 여부를 확인하는 경우에만 필요한 파일을 좁게 읽는다. 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`)
|
||||||
4
.cursorignore
Normal file
4
.cursorignore
Normal 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
55
.cursorrules
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
# 공통 규칙
|
||||||
|
|
||||||
|
**현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
|
||||||
|
|
||||||
|
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
|
||||||
|
- `agent-ops/rules/common/**`와 `agent-ops/skills/common/**`은 중앙 관리되는 공통 영역이므로 어떤 프로젝트 작업에서도 사용자가 직접 지시하지 않는 이상 절대 직접 수정하지 않는다. 프로젝트별 규칙과 스킬은 반드시 대응하는 `project/**` 영역에만 반영한다.
|
||||||
|
- 최종 답변은 한국어로 한다.
|
||||||
|
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
|
||||||
|
- 요청 범위를 넘는 변경을 하지 않는다.
|
||||||
|
- 불확실하면 단정하지 말고 후보를 제시한다.
|
||||||
|
- `agent-task/archive/**`는 일반 작업에서 읽지 않는다. 예외: 사용자가 과거 작업 확인, 복원, 비교, 특정 archive 경로 확인을 요청한 경우, active `PLAN-*.md` / `CODE_REVIEW-*.md` / `USER_REVIEW.md`가 특정 archive evidence 경로를 명시한 경우, 또는 plan/code-review 루프의 split subtask 선행 의존성 충족 여부를 확인하는 경우에만 필요한 파일을 좁게 읽는다. 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`)
|
||||||
14
.dockerignore
Normal file
14
.dockerignore
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
.dart_tool
|
||||||
|
**/.dart_tool
|
||||||
|
**/.idea
|
||||||
|
**/build
|
||||||
|
bin
|
||||||
|
coverage
|
||||||
|
*.out
|
||||||
|
*.iml
|
||||||
|
|
||||||
15
.editorconfig
Normal file
15
.editorconfig
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.go]
|
||||||
|
indent_style = tab
|
||||||
|
|
||||||
|
[{*.yaml,*.yml,*.json,*.md,*.dart}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
10
.env.example
Normal file
10
.env.example
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
ARIADNE_ENVIRONMENT=development
|
||||||
|
ARIADNE_HTTP_ADDRESS=:8080
|
||||||
|
ARIADNE_DATABASE_URL=postgres://ariadne_runtime:ariadne_runtime@localhost:15432/ariadne?sslmode=disable
|
||||||
|
ARIADNE_DATABASE_IDENTITY_URL=postgres://ariadne_identity:ariadne_identity@localhost:15432/ariadne?sslmode=disable
|
||||||
|
ARIADNE_DATABASE_MIGRATION_URL=postgres://ariadne_migrator:ariadne_migrator@localhost:15432/ariadne?sslmode=disable
|
||||||
|
ARIADNE_DATABASE_RUNTIME_ROLE=ariadne_runtime
|
||||||
|
ARIADNE_DATABASE_IDENTITY_ROLE=ariadne_identity
|
||||||
|
ARIADNE_MIGRATION_LOCK_TIMEOUT=30s
|
||||||
|
ARIADNE_IOP_ENDPOINT=
|
||||||
|
ARIADNE_SHUTDOWN_TIMEOUT=10s
|
||||||
4
.fvmrc
Normal file
4
.fvmrc
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"flutter": "3.41.5"
|
||||||
|
}
|
||||||
|
|
||||||
4
.geminiignore
Normal file
4
.geminiignore
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
# BEGIN Agent-Ops managed ignore
|
||||||
|
agent-task/archive/**
|
||||||
|
agent-roadmap/archive/**
|
||||||
|
# END Agent-Ops managed ignore
|
||||||
39
.gitignore
vendored
Normal file
39
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
# Local configuration and secrets
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Go
|
||||||
|
/bin/
|
||||||
|
/coverage/
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# Flutter and Dart
|
||||||
|
**/.dart_tool/
|
||||||
|
**/.flutter-plugins
|
||||||
|
**/.flutter-plugins-dependencies
|
||||||
|
**/.packages
|
||||||
|
**/build/
|
||||||
|
**/.idea/
|
||||||
|
**/*.iml
|
||||||
|
|
||||||
|
# Editors and operating systems
|
||||||
|
.DS_Store
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
|
||||||
|
# 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
55
AGENTS.md
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
# 공통 규칙
|
||||||
|
|
||||||
|
**현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
|
||||||
|
|
||||||
|
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
|
||||||
|
- `agent-ops/rules/common/**`와 `agent-ops/skills/common/**`은 중앙 관리되는 공통 영역이므로 어떤 프로젝트 작업에서도 사용자가 직접 지시하지 않는 이상 절대 직접 수정하지 않는다. 프로젝트별 규칙과 스킬은 반드시 대응하는 `project/**` 영역에만 반영한다.
|
||||||
|
- 최종 답변은 한국어로 한다.
|
||||||
|
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
|
||||||
|
- 요청 범위를 넘는 변경을 하지 않는다.
|
||||||
|
- 불확실하면 단정하지 말고 후보를 제시한다.
|
||||||
|
- `agent-task/archive/**`는 일반 작업에서 읽지 않는다. 예외: 사용자가 과거 작업 확인, 복원, 비교, 특정 archive 경로 확인을 요청한 경우, active `PLAN-*.md` / `CODE_REVIEW-*.md` / `USER_REVIEW.md`가 특정 archive evidence 경로를 명시한 경우, 또는 plan/code-review 루프의 split subtask 선행 의존성 충족 여부를 확인하는 경우에만 필요한 파일을 좁게 읽는다. 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`)
|
||||||
55
CLAUDE.md
Normal file
55
CLAUDE.md
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
# 공통 규칙
|
||||||
|
|
||||||
|
**현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
|
||||||
|
|
||||||
|
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
|
||||||
|
- `agent-ops/rules/common/**`와 `agent-ops/skills/common/**`은 중앙 관리되는 공통 영역이므로 어떤 프로젝트 작업에서도 사용자가 직접 지시하지 않는 이상 절대 직접 수정하지 않는다. 프로젝트별 규칙과 스킬은 반드시 대응하는 `project/**` 영역에만 반영한다.
|
||||||
|
- 최종 답변은 한국어로 한다.
|
||||||
|
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
|
||||||
|
- 요청 범위를 넘는 변경을 하지 않는다.
|
||||||
|
- 불확실하면 단정하지 말고 후보를 제시한다.
|
||||||
|
- `agent-task/archive/**`는 일반 작업에서 읽지 않는다. 예외: 사용자가 과거 작업 확인, 복원, 비교, 특정 archive 경로 확인을 요청한 경우, active `PLAN-*.md` / `CODE_REVIEW-*.md` / `USER_REVIEW.md`가 특정 archive evidence 경로를 명시한 경우, 또는 plan/code-review 루프의 split subtask 선행 의존성 충족 여부를 확인하는 경우에만 필요한 파일을 좁게 읽는다. 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`)
|
||||||
25
Dockerfile
Normal file
25
Dockerfile
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
FROM golang:1.24-bookworm AS build
|
||||||
|
|
||||||
|
WORKDIR /src
|
||||||
|
COPY go.mod go.sum ./
|
||||||
|
RUN go mod download
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
ARG VERSION=dev
|
||||||
|
RUN CGO_ENABLED=0 go build \
|
||||||
|
-trimpath \
|
||||||
|
-ldflags "-s -w -X main.version=${VERSION}" \
|
||||||
|
-o /out/ariadne \
|
||||||
|
./apps/server/cmd/ariadne
|
||||||
|
RUN CGO_ENABLED=0 go build \
|
||||||
|
-trimpath \
|
||||||
|
-ldflags "-s -w" \
|
||||||
|
-o /out/ariadne-migrate \
|
||||||
|
./apps/migrate/cmd/ariadne-migrate
|
||||||
|
|
||||||
|
FROM gcr.io/distroless/static-debian12:nonroot
|
||||||
|
|
||||||
|
COPY --from=build /out/ariadne /ariadne
|
||||||
|
COPY --from=build /out/ariadne-migrate /ariadne-migrate
|
||||||
|
EXPOSE 8080
|
||||||
|
ENTRYPOINT ["/ariadne"]
|
||||||
55
GEMINI.md
Normal file
55
GEMINI.md
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
# 공통 규칙
|
||||||
|
|
||||||
|
**현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
|
||||||
|
|
||||||
|
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
|
||||||
|
- `agent-ops/rules/common/**`와 `agent-ops/skills/common/**`은 중앙 관리되는 공통 영역이므로 어떤 프로젝트 작업에서도 사용자가 직접 지시하지 않는 이상 절대 직접 수정하지 않는다. 프로젝트별 규칙과 스킬은 반드시 대응하는 `project/**` 영역에만 반영한다.
|
||||||
|
- 최종 답변은 한국어로 한다.
|
||||||
|
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
|
||||||
|
- 요청 범위를 넘는 변경을 하지 않는다.
|
||||||
|
- 불확실하면 단정하지 말고 후보를 제시한다.
|
||||||
|
- `agent-task/archive/**`는 일반 작업에서 읽지 않는다. 예외: 사용자가 과거 작업 확인, 복원, 비교, 특정 archive 경로 확인을 요청한 경우, active `PLAN-*.md` / `CODE_REVIEW-*.md` / `USER_REVIEW.md`가 특정 archive evidence 경로를 명시한 경우, 또는 plan/code-review 루프의 split subtask 선행 의존성 충족 여부를 확인하는 경우에만 필요한 파일을 좁게 읽는다. 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`)
|
||||||
37
Makefile
Normal file
37
Makefile
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
.PHONY: all build test fmt vet migrate run client-get client-test client-analyze client-build check
|
||||||
|
|
||||||
|
all: check
|
||||||
|
|
||||||
|
build:
|
||||||
|
go build ./...
|
||||||
|
|
||||||
|
test:
|
||||||
|
go test ./...
|
||||||
|
|
||||||
|
fmt:
|
||||||
|
gofmt -w $$(find apps internal -name '*.go' -type f)
|
||||||
|
|
||||||
|
vet:
|
||||||
|
go vet ./...
|
||||||
|
|
||||||
|
migrate:
|
||||||
|
go run ./apps/migrate/cmd/ariadne-migrate
|
||||||
|
|
||||||
|
run:
|
||||||
|
go run ./apps/server/cmd/ariadne
|
||||||
|
|
||||||
|
client-get:
|
||||||
|
cd apps/client && flutter pub get --enforce-lockfile
|
||||||
|
|
||||||
|
client-test:
|
||||||
|
cd apps/client && flutter test
|
||||||
|
|
||||||
|
client-analyze:
|
||||||
|
cd apps/client && flutter analyze
|
||||||
|
|
||||||
|
client-build:
|
||||||
|
cd apps/client && flutter build web --release
|
||||||
|
|
||||||
|
client-test client-analyze client-build: client-get
|
||||||
|
|
||||||
|
check: build test vet client-test client-analyze client-build
|
||||||
156
README.md
Normal file
156
README.md
Normal file
|
|
@ -0,0 +1,156 @@
|
||||||
|
# Ariadne
|
||||||
|
|
||||||
|
Ariadne는 여러 조직에서 발생하는 오류를 통합하고, 연결된 저장소와 읽기 전용 실행 환경을 분석해 수정·검증·병합 요청까지 이어 주는 플랫폼이다.
|
||||||
|
|
||||||
|
오류 분석과 수정 작업에는 IOP의 LLM 호출 및 CLI 실행 기능을 사용한다. 오류 이력, 조직과 권한, 연결 대상, 작업 흐름, 승인, 보고, 감사 기록의 기준 시스템은 Ariadne다.
|
||||||
|
|
||||||
|
## 현재 상태
|
||||||
|
|
||||||
|
Ariadne는 현재 기반 스캐폴드를 안정화하는 단계다.
|
||||||
|
|
||||||
|
- Go 서버의 설정, 로깅, PostgreSQL 연결, 마이그레이션, 조직 격리 기반과 상태 확인 endpoint가 구현되어 있다.
|
||||||
|
- Flutter 웹에는 반응형 운영 화면의 개요 스캐폴드가 있다.
|
||||||
|
- 외부 오류 입력과 IOP 실행·실패 형식은 버전별 JSON Schema로 관리한다.
|
||||||
|
- 현재 서버가 노출하는 HTTP endpoint는 `GET /healthz`와 `GET /readyz`다.
|
||||||
|
- 최초 사용자·조직 생성, 오류 수집 API, 분석·수정 workflow, 병합 요청 전달은 아직 제공하지 않는다.
|
||||||
|
|
||||||
|
제품 방향과 구현 순서는 [로드맵](agent-roadmap/ROADMAP.md)과 [전역 Milestone 실행 순서](agent-roadmap/priority-queue.md)에서 확인한다.
|
||||||
|
|
||||||
|
## 빠른 시작
|
||||||
|
|
||||||
|
### 요구 도구
|
||||||
|
|
||||||
|
- Go 1.24 이상
|
||||||
|
- Flutter 3.41.5 / Dart 3.11
|
||||||
|
- Docker Compose
|
||||||
|
|
||||||
|
### 서버와 PostgreSQL
|
||||||
|
|
||||||
|
개발용 PostgreSQL, 마이그레이션, 서버를 함께 실행한다.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker compose up --build
|
||||||
|
```
|
||||||
|
|
||||||
|
실행 후 상태를 확인한다.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl http://localhost:18080/healthz
|
||||||
|
curl http://localhost:18080/readyz
|
||||||
|
```
|
||||||
|
|
||||||
|
로컬 Go 도구로 서버를 직접 실행하려면 먼저 PostgreSQL만 시작하고 `.env.example`의 환경 변수를 내보낸다.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker compose up -d database
|
||||||
|
set -a
|
||||||
|
. ./.env.example
|
||||||
|
set +a
|
||||||
|
make migrate
|
||||||
|
make run
|
||||||
|
```
|
||||||
|
|
||||||
|
직접 실행한 서버의 기본 주소는 `http://localhost:8080`이다. 데이터베이스 설정 없이도 서버는 시작할 수 있지만 `/readyz`는 준비되지 않은 상태를 반환한다.
|
||||||
|
|
||||||
|
### Flutter 웹
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make client-get
|
||||||
|
cd apps/client
|
||||||
|
flutter run -d chrome
|
||||||
|
```
|
||||||
|
|
||||||
|
## 주요 명령
|
||||||
|
|
||||||
|
| 목적 | 명령 | 비고 |
|
||||||
|
|------|------|------|
|
||||||
|
| 전체 개발 환경 실행 | `docker compose up --build` | PostgreSQL, migration, Go 서버 |
|
||||||
|
| Go 서버 실행 | `make run` | `.env.example` 기준 환경 변수 필요 |
|
||||||
|
| DB migration 적용 | `make migrate` | migration 전용 DB 역할 사용 |
|
||||||
|
| Go build | `make build` | `go build ./...` |
|
||||||
|
| Go test | `make test` | `go test ./...` |
|
||||||
|
| Go 정적 검사 | `make vet` | `go vet ./...` |
|
||||||
|
| Go format | `make fmt` | `apps/`, `internal/`의 Go 파일 수정 |
|
||||||
|
| Flutter 의존성 설치 | `make client-get` | lockfile 강제 사용 |
|
||||||
|
| Flutter test | `make client-test` | 의존성 설치 포함 |
|
||||||
|
| Flutter 정적 분석 | `make client-analyze` | 의존성 설치 포함 |
|
||||||
|
| Flutter web release build | `make client-build` | 의존성 설치 포함 |
|
||||||
|
| 전체 기본 검사 | `make check` | Go build/test/vet와 Flutter test/analyze/build |
|
||||||
|
|
||||||
|
## 구조
|
||||||
|
|
||||||
|
| 경로 | 역할 |
|
||||||
|
|------|------|
|
||||||
|
| `apps/server/cmd/ariadne/` | Go 서버 진입점 |
|
||||||
|
| `apps/migrate/cmd/ariadne-migrate/` | 전용 DB migration 명령 |
|
||||||
|
| `apps/client/` | Flutter 웹 사용자 화면 |
|
||||||
|
| `internal/domain/` | 조직, 오류, 실패, 수정 작업의 핵심 모델과 규칙 |
|
||||||
|
| `internal/integration/` | IOP 등 외부 실행 계층과의 adapter 경계 |
|
||||||
|
| `internal/platform/` | 설정, 로깅, DB, HTTP 서버, bootstrap |
|
||||||
|
| `contracts/` | 외부 오류 입력과 IOP 실행·실패 JSON 계약 |
|
||||||
|
| `deploy/` | 개발·배포 기반 구성 |
|
||||||
|
| `docs/` | 사람을 위한 최신 구조·개발 가이드 |
|
||||||
|
| `agent-ops/` | AI 작업 규칙과 프로젝트 workflow |
|
||||||
|
| `agent-roadmap/` | 제품 방향, Phase, Milestone |
|
||||||
|
|
||||||
|
## 핵심 처리 정책
|
||||||
|
|
||||||
|
Ariadne는 다음 두 가지 수정 흐름을 지원하는 방향으로 개발한다.
|
||||||
|
|
||||||
|
- **수정 전 보고**: 오류 분석 → 수정 가능 여부와 수정안 보고 → 사용자 승인 → 수정 및 검증 → 병합 요청
|
||||||
|
- **자동 수정 후 보고**: 오류 분석 → 가능한 경우 자동 수정 및 검증 → 결과 보고와 병합 요청
|
||||||
|
|
||||||
|
자동 수정이 불가능하거나 검증에 실패하면 저장소를 변경하지 않고 분석 결과만 보고한다. 병합은 항상 사용자가 승인한다.
|
||||||
|
|
||||||
|
오류 입력 자격 증명은 조직과 프로젝트에 귀속된다. 입력 본문이 조직이나 프로젝트를 임의로 선택하지 않으며, 등록된 출처 규칙이 오류의 저장소와 읽기 전용 실행 환경을 결정한다.
|
||||||
|
|
||||||
|
IOP의 언어와 운영 관례는 공유하지만 IOP의 제어부·edge·실행 node 계층을 복제하지 않는다. Ariadne는 독립적으로 build·배포할 수 있어야 한다.
|
||||||
|
|
||||||
|
## 작업 맥락
|
||||||
|
|
||||||
|
- 작업 전 루트 [AGENTS.md](AGENTS.md)와 [프로젝트 규칙](agent-ops/rules/project/rules.md)을 먼저 확인한다.
|
||||||
|
- 변경 경로에 대응하는 domain rule을 코드 변경 전에 읽는다.
|
||||||
|
- `internal/domain/**`: [domain-model](agent-ops/rules/project/domain/domain-model/rules.md)
|
||||||
|
- `internal/integration/**`, `contracts/**`: [integrations](agent-ops/rules/project/domain/integrations/rules.md)
|
||||||
|
- `internal/platform/**`, `apps/server/**`, `apps/migrate/**`, `deploy/**`: [platform](agent-ops/rules/project/domain/platform/rules.md)
|
||||||
|
- `apps/client/**`, `.fvmrc`: [client](agent-ops/rules/project/domain/client/rules.md)
|
||||||
|
- 로컬 활성 후보는 `agent-roadmap/current.md`, 공유 제품 방향은 [로드맵](agent-roadmap/ROADMAP.md)에서 확인한다.
|
||||||
|
- 조직 소유 데이터는 반드시 조직 범위 transaction과 강제 RLS 경계 안에서 접근한다.
|
||||||
|
- migration, 서버 runtime, identity 조회 DB 역할을 분리하고 runtime pool을 조직 범위 밖으로 노출하지 않는다.
|
||||||
|
- 운영 환경 연결은 읽기 전용이다. 별도 권한·승인 설계 없이 쓰기 기능이나 IOP의 직접 merge 권한을 추가하지 않는다.
|
||||||
|
- 로컬 형제 저장소를 정식 build dependency로 사용하지 않는다.
|
||||||
|
|
||||||
|
## 개발 흐름
|
||||||
|
|
||||||
|
1. 로드맵과 변경 경로의 domain rule에서 범위와 제약을 확인한다.
|
||||||
|
2. 기존 package와 directory 경계를 유지하며 구현한다.
|
||||||
|
3. DB 변경은 `internal/platform/database/migrations/`에 순서가 보장되는 새 migration으로 추가한다. 적용된 migration의 checksum은 바꾸지 않는다.
|
||||||
|
4. 변경 범위별 test와 정적 검사를 실행한다.
|
||||||
|
5. 전체 검증이 필요하면 `make check`를 실행한다.
|
||||||
|
|
||||||
|
PostgreSQL 권한·RLS 통합 검사는 Docker 사용 가능 여부와 전용 역할 환경 변수를 확인한 뒤 별도로 수행한다. 자세한 절차는 [개발 가이드](docs/development.md)를 따른다.
|
||||||
|
|
||||||
|
## 환경 변수
|
||||||
|
|
||||||
|
`.env.example`은 로컬 실행용 개발 값을 제공한다. 실제 비밀값이 있는 `.env`는 저장소에 commit하지 않는다.
|
||||||
|
|
||||||
|
| 이름 | 설명 | 필수 |
|
||||||
|
|------|------|------|
|
||||||
|
| `ARIADNE_ENVIRONMENT` | 실행 환경 이름, 기본값 `development` | 아니오 |
|
||||||
|
| `ARIADNE_HTTP_ADDRESS` | HTTP 수신 주소, 기본값 `:8080` | 아니오 |
|
||||||
|
| `ARIADNE_DATABASE_URL` | runtime 역할의 PostgreSQL 접속 주소 | DB 준비 상태에 필요 |
|
||||||
|
| `ARIADNE_DATABASE_IDENTITY_URL` | identity 조회 역할의 PostgreSQL 접속 주소 | DB 준비 상태에 필요 |
|
||||||
|
| `ARIADNE_DATABASE_MIGRATION_URL` | migration 전용 PostgreSQL 접속 주소 | migration 시 필요 |
|
||||||
|
| `ARIADNE_DATABASE_RUNTIME_ROLE` | 기대하는 runtime DB 역할 이름 | DB 사용 시 필요 |
|
||||||
|
| `ARIADNE_DATABASE_IDENTITY_ROLE` | 기대하는 identity DB 역할 이름 | DB 사용 시 필요 |
|
||||||
|
| `ARIADNE_MIGRATION_LOCK_TIMEOUT` | 동시 migration lock 대기 한도, 기본값 `30s` | 아니오 |
|
||||||
|
| `ARIADNE_IOP_ENDPOINT` | IOP 연결 주소 | 현재 아니오 |
|
||||||
|
| `ARIADNE_SHUTDOWN_TIMEOUT` | 정상 종료 대기 시간, 기본값 `10s` | 아니오 |
|
||||||
|
|
||||||
|
## 참고 문서
|
||||||
|
|
||||||
|
- [아키텍처와 책임 경계](docs/architecture.md)
|
||||||
|
- [개발 환경과 DB 변경 지침](docs/development.md)
|
||||||
|
- [외부 JSON 계약](contracts/README.md)
|
||||||
|
- [Flutter client 안내](apps/client/README.md)
|
||||||
|
- [프로젝트 로드맵](agent-roadmap/ROADMAP.md)
|
||||||
1
agent-ops/.version
Normal file
1
agent-ops/.version
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
1.1.170
|
||||||
260
agent-ops/bin/ai-ignore.sh
Executable file
260
agent-ops/bin/ai-ignore.sh
Executable file
|
|
@ -0,0 +1,260 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Shared AI ignore / permission defaults for init and sync flows.
|
||||||
|
AGENT_OPS_TASK_ARCHIVE_IGNORE_PATTERN="agent-task/archive/**"
|
||||||
|
AGENT_ROADMAP_ARCHIVE_IGNORE_PATTERN="agent-roadmap/archive/**"
|
||||||
|
AGENT_ROADMAP_CURRENT_LOCAL_PATTERN="agent-roadmap/current.md"
|
||||||
|
AGENT_OPS_AI_IGNORE_BLOCK_BEGIN="# BEGIN Agent-Ops managed ignore"
|
||||||
|
AGENT_OPS_AI_IGNORE_BLOCK_END="# END Agent-Ops managed ignore"
|
||||||
|
AGENT_OPS_GITIGNORE_BLOCK_BEGIN="# BEGIN Agent-Ops managed gitignore"
|
||||||
|
AGENT_OPS_GITIGNORE_BLOCK_END="# END Agent-Ops managed gitignore"
|
||||||
|
AGENT_OPS_AI_IGNORE_FILES=(".geminiignore" ".aiexclude" ".cursorignore" ".clineignore")
|
||||||
|
AGENT_OPS_AI_PERMISSION_FILES=(".claude/settings.json" "opencode.json")
|
||||||
|
AGENT_OPS_AI_SYNC_FILES=(".gitignore" "${AGENT_OPS_AI_IGNORE_FILES[@]}" "${AGENT_OPS_AI_PERMISSION_FILES[@]}")
|
||||||
|
|
||||||
|
agent_ops_ensure_gitignore_task_artifact_block() {
|
||||||
|
local file="$1"
|
||||||
|
local tmp
|
||||||
|
|
||||||
|
touch "$file"
|
||||||
|
if grep -qxF "$AGENT_OPS_GITIGNORE_BLOCK_BEGIN" "$file" \
|
||||||
|
&& grep -qxF "$AGENT_OPS_GITIGNORE_BLOCK_END" "$file"; then
|
||||||
|
tmp="$(mktemp "$file.tmp.XXXXXX")"
|
||||||
|
awk \
|
||||||
|
-v begin="$AGENT_OPS_GITIGNORE_BLOCK_BEGIN" \
|
||||||
|
-v end="$AGENT_OPS_GITIGNORE_BLOCK_END" \
|
||||||
|
-v current="$AGENT_ROADMAP_CURRENT_LOCAL_PATTERN" '
|
||||||
|
$0 == begin {
|
||||||
|
print begin
|
||||||
|
print "!agent-task/"
|
||||||
|
print "!agent-task/**/"
|
||||||
|
print "!agent-task/**/*.md"
|
||||||
|
print "!agent-task/**/*.log"
|
||||||
|
print current
|
||||||
|
print end
|
||||||
|
in_block = 1
|
||||||
|
next
|
||||||
|
}
|
||||||
|
$0 == end && in_block {
|
||||||
|
in_block = 0
|
||||||
|
next
|
||||||
|
}
|
||||||
|
!in_block { print }
|
||||||
|
' "$file" > "$tmp"
|
||||||
|
mv "$tmp" "$file"
|
||||||
|
else
|
||||||
|
if [[ -s "$file" ]]; then
|
||||||
|
printf "\n" >> "$file"
|
||||||
|
fi
|
||||||
|
printf "%s\n" "$AGENT_OPS_GITIGNORE_BLOCK_BEGIN" >> "$file"
|
||||||
|
printf "%s\n" "!agent-task/" >> "$file"
|
||||||
|
printf "%s\n" "!agent-task/**/" >> "$file"
|
||||||
|
printf "%s\n" "!agent-task/**/*.md" >> "$file"
|
||||||
|
printf "%s\n" "!agent-task/**/*.log" >> "$file"
|
||||||
|
printf "%s\n" "$AGENT_ROADMAP_CURRENT_LOCAL_PATTERN" >> "$file"
|
||||||
|
printf "%s\n" "$AGENT_OPS_GITIGNORE_BLOCK_END" >> "$file"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
agent_ops_ensure_ai_ignore_block() {
|
||||||
|
local file="$1"
|
||||||
|
local tmp
|
||||||
|
|
||||||
|
touch "$file"
|
||||||
|
if grep -qxF "$AGENT_OPS_AI_IGNORE_BLOCK_BEGIN" "$file" \
|
||||||
|
&& grep -qxF "$AGENT_OPS_AI_IGNORE_BLOCK_END" "$file"; then
|
||||||
|
tmp="$(mktemp "$file.tmp.XXXXXX")"
|
||||||
|
awk \
|
||||||
|
-v begin="$AGENT_OPS_AI_IGNORE_BLOCK_BEGIN" \
|
||||||
|
-v end="$AGENT_OPS_AI_IGNORE_BLOCK_END" \
|
||||||
|
-v task="$AGENT_OPS_TASK_ARCHIVE_IGNORE_PATTERN" \
|
||||||
|
-v roadmap="$AGENT_ROADMAP_ARCHIVE_IGNORE_PATTERN" '
|
||||||
|
$0 == begin {
|
||||||
|
print begin
|
||||||
|
print task
|
||||||
|
print roadmap
|
||||||
|
print end
|
||||||
|
in_block = 1
|
||||||
|
next
|
||||||
|
}
|
||||||
|
$0 == end && in_block {
|
||||||
|
in_block = 0
|
||||||
|
next
|
||||||
|
}
|
||||||
|
!in_block { print }
|
||||||
|
' "$file" > "$tmp"
|
||||||
|
mv "$tmp" "$file"
|
||||||
|
else
|
||||||
|
if [[ -s "$file" ]]; then
|
||||||
|
printf "\n" >> "$file"
|
||||||
|
fi
|
||||||
|
printf "%s\n" "$AGENT_OPS_AI_IGNORE_BLOCK_BEGIN" >> "$file"
|
||||||
|
printf "%s\n" "$AGENT_OPS_TASK_ARCHIVE_IGNORE_PATTERN" >> "$file"
|
||||||
|
printf "%s\n" "$AGENT_ROADMAP_ARCHIVE_IGNORE_PATTERN" >> "$file"
|
||||||
|
printf "%s\n" "$AGENT_OPS_AI_IGNORE_BLOCK_END" >> "$file"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
agent_ops_merge_json_with_jq() {
|
||||||
|
local file="$1"
|
||||||
|
local filter="$2"
|
||||||
|
local fallback_note="$3"
|
||||||
|
local tmp
|
||||||
|
|
||||||
|
if ! command -v jq >/dev/null 2>&1; then
|
||||||
|
echo "$fallback_note"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
tmp="$(mktemp "$file.tmp.XXXXXX")"
|
||||||
|
if jq "$filter" "$file" > "$tmp"; then
|
||||||
|
mv "$tmp" "$file"
|
||||||
|
else
|
||||||
|
rm -f "$tmp"
|
||||||
|
echo "$fallback_note"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
agent_ops_merge_claude_settings() {
|
||||||
|
local file="$1"
|
||||||
|
local filter='
|
||||||
|
def as_array:
|
||||||
|
if type == "array" then . elif . == null then [] else [.] end;
|
||||||
|
def as_object:
|
||||||
|
if type == "object" then . else {} end;
|
||||||
|
|
||||||
|
.permissions = ((.permissions // {}) | as_object)
|
||||||
|
| .permissions.deny = (
|
||||||
|
(.permissions.deny | as_array)
|
||||||
|
| map(select(. != "Read(./agent-roadmap/archive/**)"))
|
||||||
|
| map(select(. != "Read(./agent-task/archive/**)"))
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
agent_ops_merge_json_with_jq \
|
||||||
|
"$file" \
|
||||||
|
"$filter" \
|
||||||
|
"Note: .claude/settings.json exists; remove Read(./agent-task/archive/**) and Read(./agent-roadmap/archive/**) manually."
|
||||||
|
}
|
||||||
|
|
||||||
|
agent_ops_claude_settings_complete() {
|
||||||
|
local file="$1"
|
||||||
|
local filter='
|
||||||
|
def as_array:
|
||||||
|
if type == "array" then . elif . == null then [] else [.] end;
|
||||||
|
|
||||||
|
(.permissions.deny | as_array)
|
||||||
|
as $deny
|
||||||
|
| (($deny | index("Read(./agent-task/archive/**)")) == null)
|
||||||
|
and (($deny | index("Read(./agent-roadmap/archive/**)")) == null)
|
||||||
|
'
|
||||||
|
|
||||||
|
if command -v jq >/dev/null 2>&1; then
|
||||||
|
jq -e "$filter" "$file" >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
! grep -qF "Read(./agent-task/archive/**)" "$file" \
|
||||||
|
&& ! grep -qF "Read(./agent-roadmap/archive/**)" "$file"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
agent_ops_merge_opencode_config() {
|
||||||
|
local file="$1"
|
||||||
|
local filter='
|
||||||
|
def append_unique($item):
|
||||||
|
if index($item) then . else . + [$item] end;
|
||||||
|
def as_array:
|
||||||
|
if type == "array" then . elif . == null then [] else [.] end;
|
||||||
|
def as_object:
|
||||||
|
if type == "object" then . else {} end;
|
||||||
|
|
||||||
|
.permission = ((.permission // {}) | as_object)
|
||||||
|
| .permission.read = ((.permission.read // {}) | as_object)
|
||||||
|
| del(.permission.read["agent-task/archive/**"])
|
||||||
|
| del(.permission.read["agent-roadmap/archive/**"])
|
||||||
|
| .permission.glob = ((.permission.glob // {}) | as_object)
|
||||||
|
| del(.permission.glob["agent-task/archive/**"])
|
||||||
|
| del(.permission.glob["agent-roadmap/archive/**"])
|
||||||
|
| .watcher = ((.watcher // {}) | as_object)
|
||||||
|
| .watcher.ignore = (
|
||||||
|
(.watcher.ignore | as_array)
|
||||||
|
| append_unique("agent-task/archive/**")
|
||||||
|
| append_unique("agent-roadmap/archive/**")
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
agent_ops_merge_json_with_jq \
|
||||||
|
"$file" \
|
||||||
|
"$filter" \
|
||||||
|
"Note: opencode.json exists; remove agent-task/archive/** and agent-roadmap/archive/** read/glob hard deny, and add both archive paths to watcher ignore manually."
|
||||||
|
}
|
||||||
|
|
||||||
|
agent_ops_opencode_config_complete() {
|
||||||
|
local file="$1"
|
||||||
|
local filter='
|
||||||
|
def as_array:
|
||||||
|
if type == "array" then . elif . == null then [] else [.] end;
|
||||||
|
|
||||||
|
(.permission.read["agent-task/archive/**"] != "deny")
|
||||||
|
and (.permission.glob["agent-task/archive/**"] != "deny")
|
||||||
|
and (.permission.read["agent-roadmap/archive/**"] != "deny")
|
||||||
|
and (.permission.glob["agent-roadmap/archive/**"] != "deny")
|
||||||
|
and ((.watcher.ignore | as_array) as $ignore | (($ignore | index("agent-task/archive/**")) != null) and (($ignore | index("agent-roadmap/archive/**")) != null))
|
||||||
|
'
|
||||||
|
|
||||||
|
if command -v jq >/dev/null 2>&1; then
|
||||||
|
jq -e "$filter" "$file" >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
grep -qF "agent-task/archive" "$file" \
|
||||||
|
&& grep -qF "agent-roadmap/archive" "$file" \
|
||||||
|
&& ! grep -qF "\"agent-task/archive/**\": \"deny\"" "$file" \
|
||||||
|
&& ! grep -qF "\"agent-roadmap/archive/**\": \"deny\"" "$file"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_agent_ops_ai_ignore_config() {
|
||||||
|
local target_dir="$1"
|
||||||
|
local ignore_file
|
||||||
|
|
||||||
|
if [[ -f "$target_dir/.agent-ops-source" ]]; then
|
||||||
|
echo " AI ignore 보강 건너뜀: .agent-ops-source repo"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
agent_ops_ensure_gitignore_task_artifact_block "$target_dir/.gitignore"
|
||||||
|
|
||||||
|
for ignore_file in "${AGENT_OPS_AI_IGNORE_FILES[@]}"; do
|
||||||
|
agent_ops_ensure_ai_ignore_block "$target_dir/$ignore_file"
|
||||||
|
done
|
||||||
|
|
||||||
|
mkdir -p "$target_dir/.claude"
|
||||||
|
if [[ ! -f "$target_dir/.claude/settings.json" ]]; then
|
||||||
|
cat > "$target_dir/.claude/settings.json" <<'EOF'
|
||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
||||||
|
"permissions": {
|
||||||
|
"deny": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
elif ! agent_ops_claude_settings_complete "$target_dir/.claude/settings.json"; then
|
||||||
|
agent_ops_merge_claude_settings "$target_dir/.claude/settings.json"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "$target_dir/opencode.json" ]]; then
|
||||||
|
cat > "$target_dir/opencode.json" <<'EOF'
|
||||||
|
{
|
||||||
|
"$schema": "https://opencode.ai/config.json",
|
||||||
|
"watcher": {
|
||||||
|
"ignore": [
|
||||||
|
"agent-task/archive/**",
|
||||||
|
"agent-roadmap/archive/**"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
elif ! agent_ops_opencode_config_complete "$target_dir/opencode.json"; then
|
||||||
|
agent_ops_merge_opencode_config "$target_dir/opencode.json"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo " AI permission 표준 적용: archive hard deny 제거, archive ignore 적용"
|
||||||
|
}
|
||||||
28
agent-ops/bin/bump-version.sh
Executable file
28
agent-ops/bin/bump-version.sh
Executable file
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# bump-version.sh <version>
|
||||||
|
# patch +1, 999 초과 시 minor 올림. major는 수동 관리.
|
||||||
|
# 결과 버전을 stdout으로 출력.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
YELLOW='\033[1;33m'; RESET='\033[0m'
|
||||||
|
|
||||||
|
VERSION="${1:-}"
|
||||||
|
if [[ -z "$VERSION" ]]; then
|
||||||
|
echo "사용법: $0 <major.minor.patch>" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
IFS='.' read -r major minor patch <<< "$VERSION"
|
||||||
|
|
||||||
|
patch=$((patch + 1))
|
||||||
|
if [[ $patch -gt 999 ]]; then
|
||||||
|
patch=0
|
||||||
|
minor=$((minor + 1))
|
||||||
|
fi
|
||||||
|
if [[ $minor -gt 999 ]]; then
|
||||||
|
minor=0
|
||||||
|
echo -e "${YELLOW}⚠ minor 버전이 999를 초과했습니다. major 버전을 수동으로 올려주세요.${RESET}" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$major.$minor.$patch"
|
||||||
24
agent-ops/bin/entry-files.sh
Normal file
24
agent-ops/bin/entry-files.sh
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Shared entry-point file list for init/sync scripts.
|
||||||
|
AGENT_OPS_ENTRY_FILES=("GEMINI.md" "CLAUDE.md" "AGENTS.md" ".cursorrules" ".clinerules")
|
||||||
|
|
||||||
|
apply_agent_ops_entry_files() {
|
||||||
|
local rules_md="$1"
|
||||||
|
local target_root="$2"
|
||||||
|
|
||||||
|
if [[ ! -f "$rules_md" ]]; then
|
||||||
|
if [[ -n "${YELLOW:-}" && -n "${RESET:-}" ]]; then
|
||||||
|
echo -e "${YELLOW} rules.md 없음, 진입 파일 재적용 건너뜀${RESET}"
|
||||||
|
else
|
||||||
|
echo " rules.md 없음, 진입 파일 재적용 건너뜀"
|
||||||
|
fi
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local f
|
||||||
|
for f in "${AGENT_OPS_ENTRY_FILES[@]}"; do
|
||||||
|
cp "$rules_md" "$target_root/$f"
|
||||||
|
echo " 진입 파일 적용: $f"
|
||||||
|
done
|
||||||
|
}
|
||||||
343
agent-ops/bin/init-agent-ops.sh
Executable file
343
agent-ops/bin/init-agent-ops.sh
Executable file
|
|
@ -0,0 +1,343 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# agent-ops/bin/init-agent-ops.sh
|
||||||
|
# 프로젝트에 agent-ops 스캐폴드를 초기화하는 스크립트
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR=$(realpath "$(dirname "$0")")
|
||||||
|
SOURCE_DIR=$(realpath "$SCRIPT_DIR/..")
|
||||||
|
source "$SCRIPT_DIR/entry-files.sh"
|
||||||
|
source "$SCRIPT_DIR/ai-ignore.sh"
|
||||||
|
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
echo "Usage: $0 <target_directory>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
TARGET_DIR=$(realpath "$1")
|
||||||
|
|
||||||
|
create_project_agent_ops_dirs() {
|
||||||
|
local agent_ops_dir="$1"
|
||||||
|
|
||||||
|
mkdir -p "$agent_ops_dir/rules/project/domain"
|
||||||
|
mkdir -p "$agent_ops_dir/rules/private"
|
||||||
|
mkdir -p "$agent_ops_dir/skills/project"
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_common_agent_ops() {
|
||||||
|
local source_dir="$1"
|
||||||
|
local target_agent_ops_dir="$2"
|
||||||
|
|
||||||
|
mkdir -p "$target_agent_ops_dir/rules"
|
||||||
|
mkdir -p "$target_agent_ops_dir/skills"
|
||||||
|
|
||||||
|
cp "$source_dir/.version" "$target_agent_ops_dir/"
|
||||||
|
rm -rf "$target_agent_ops_dir/bin"
|
||||||
|
rm -rf "$target_agent_ops_dir/rules/common"
|
||||||
|
rm -rf "$target_agent_ops_dir/skills/common"
|
||||||
|
cp -r "$source_dir/bin" "$target_agent_ops_dir/"
|
||||||
|
cp -r "$source_dir/rules/common" "$target_agent_ops_dir/rules/"
|
||||||
|
cp -r "$source_dir/skills/common" "$target_agent_ops_dir/skills/"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_common_rules_file() {
|
||||||
|
local source_dir="$1"
|
||||||
|
local target_agent_ops_dir="$2"
|
||||||
|
local source_rules="$source_dir/rules/common/rules.md"
|
||||||
|
local target_rules="$target_agent_ops_dir/rules/common/rules.md"
|
||||||
|
|
||||||
|
if [ ! -f "$source_rules" ]; then
|
||||||
|
echo "Error: common rules file not found: $source_rules" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "$target_rules")"
|
||||||
|
cp "$source_rules" "$target_rules"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_gitignore_entry() {
|
||||||
|
local gitignore_file="$1"
|
||||||
|
local entry="$2"
|
||||||
|
|
||||||
|
if ! grep -qxF "$entry" "$gitignore_file"; then
|
||||||
|
printf '%s\n' "$entry" >> "$gitignore_file"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
discover_agent_test_domains() {
|
||||||
|
local target_dir="$1"
|
||||||
|
local domain_root="$target_dir/agent-ops/rules/project/domain"
|
||||||
|
local project_rules="$target_dir/agent-ops/rules/project/rules.md"
|
||||||
|
|
||||||
|
if [ -d "$domain_root" ]; then
|
||||||
|
find "$domain_root" -mindepth 2 -maxdepth 2 -name rules.md -print \
|
||||||
|
| while IFS= read -r rule_file; do
|
||||||
|
basename "$(dirname "$rule_file")"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$project_rules" ]; then
|
||||||
|
grep -Eo 'agent-ops/rules/project/domain/[^/`[:space:]]+/rules\.md' "$project_rules" \
|
||||||
|
| awk -F/ '{ print $(NF-1) }'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_agent_test_route() {
|
||||||
|
local rules_file="$1"
|
||||||
|
local route_line="$2"
|
||||||
|
local placeholder="- 현재 등록된 도메인/검증 시나리오별 테스트 문서 없음."
|
||||||
|
local tmp
|
||||||
|
|
||||||
|
if grep -qxF -- "$route_line" "$rules_file"; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
tmp="$(mktemp "$rules_file.tmp.XXXXXX")"
|
||||||
|
if grep -qxF -- "$placeholder" "$rules_file"; then
|
||||||
|
awk -v placeholder="$placeholder" -v route_line="$route_line" '
|
||||||
|
$0 == placeholder { print route_line; next }
|
||||||
|
{ print }
|
||||||
|
' "$rules_file" > "$tmp"
|
||||||
|
else
|
||||||
|
awk -v route_line="$route_line" '
|
||||||
|
BEGIN { added = 0 }
|
||||||
|
{ print }
|
||||||
|
!added && $0 == "## 라우팅" {
|
||||||
|
print ""
|
||||||
|
print route_line
|
||||||
|
added = 1
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
if (!added) {
|
||||||
|
print ""
|
||||||
|
print "## 라우팅"
|
||||||
|
print ""
|
||||||
|
print route_line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
' "$rules_file" > "$tmp"
|
||||||
|
fi
|
||||||
|
mv "$tmp" "$rules_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_agent_test_profile() {
|
||||||
|
local target_dir="$1"
|
||||||
|
local env="$2"
|
||||||
|
local profile="$3"
|
||||||
|
local domain="$4"
|
||||||
|
local verification_type="$5"
|
||||||
|
local scope="$6"
|
||||||
|
local today="$7"
|
||||||
|
local profile_file="$target_dir/agent-test/$env/$profile.md"
|
||||||
|
local rules_file="$target_dir/agent-test/$env/rules.md"
|
||||||
|
local route_line
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "$profile_file")"
|
||||||
|
|
||||||
|
if [ ! -f "$profile_file" ]; then
|
||||||
|
cat > "$profile_file" <<EOF
|
||||||
|
---
|
||||||
|
test_env: $env
|
||||||
|
test_profile: $profile
|
||||||
|
domain: $domain
|
||||||
|
verification_type: $verification_type
|
||||||
|
last_rule_updated_at: $today
|
||||||
|
---
|
||||||
|
|
||||||
|
# $profile $env 테스트
|
||||||
|
|
||||||
|
## 읽기 조건
|
||||||
|
|
||||||
|
- $domain 도메인 또는 $scope 검증 기준이 필요한 경우
|
||||||
|
|
||||||
|
## 적용 범위
|
||||||
|
|
||||||
|
- <확인 필요>
|
||||||
|
|
||||||
|
## 분류
|
||||||
|
|
||||||
|
- domain: $domain
|
||||||
|
- verification_type: $verification_type
|
||||||
|
- scope: $scope
|
||||||
|
|
||||||
|
## 환경
|
||||||
|
|
||||||
|
- host:
|
||||||
|
- port:
|
||||||
|
- runtime:
|
||||||
|
- package manager:
|
||||||
|
- docker:
|
||||||
|
- external service:
|
||||||
|
- model endpoint:
|
||||||
|
- credential:
|
||||||
|
|
||||||
|
## 명령
|
||||||
|
|
||||||
|
- setup:
|
||||||
|
- lint:
|
||||||
|
- unit:
|
||||||
|
- smoke:
|
||||||
|
- e2e:
|
||||||
|
- model:
|
||||||
|
- full-cycle:
|
||||||
|
|
||||||
|
## 필수 검증
|
||||||
|
|
||||||
|
- <확인 필요>
|
||||||
|
|
||||||
|
## 보조 검증
|
||||||
|
|
||||||
|
- <확인 필요>
|
||||||
|
|
||||||
|
## 판정 기준
|
||||||
|
|
||||||
|
- <확인 필요>
|
||||||
|
|
||||||
|
## 기준 출력 예시
|
||||||
|
|
||||||
|
\`\`\`text
|
||||||
|
<필요한 경우 기대 출력 예시>
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
## 차단 기준
|
||||||
|
|
||||||
|
- <확인 필요>
|
||||||
|
|
||||||
|
## 보고 항목
|
||||||
|
|
||||||
|
- 실행한 명령:
|
||||||
|
- 성공한 검증:
|
||||||
|
- 실패/차단된 검증:
|
||||||
|
- 생략 사유:
|
||||||
|
- 남은 위험:
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- 확인되지 않은 host, port, token, endpoint를 추측해 쓰지 않는다.
|
||||||
|
- secret, token, 개인 endpoint 원문은 tracked 파일에 기록하지 않는다.
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
route_line="- $domain / $verification_type / $scope: \`agent-test/$env/$profile.md\`"
|
||||||
|
ensure_agent_test_route "$rules_file" "$route_line"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_agent_test_local() {
|
||||||
|
local target_dir="$1"
|
||||||
|
local local_rules="$target_dir/agent-test/local/rules.md"
|
||||||
|
local today
|
||||||
|
local domain
|
||||||
|
local created_domain_profile="0"
|
||||||
|
|
||||||
|
today="$(date +%F)"
|
||||||
|
mkdir -p "$(dirname "$local_rules")"
|
||||||
|
mkdir -p "$target_dir/agent-test/runs"
|
||||||
|
|
||||||
|
if [ ! -f "$local_rules" ]; then
|
||||||
|
cat > "$local_rules" <<EOF
|
||||||
|
---
|
||||||
|
test_env: local
|
||||||
|
last_rule_updated_at: $today
|
||||||
|
---
|
||||||
|
|
||||||
|
# local 테스트 규칙
|
||||||
|
|
||||||
|
**현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
|
||||||
|
|
||||||
|
## 공통 규칙
|
||||||
|
|
||||||
|
- local 테스트/검증은 이 파일을 기준으로 판단한다.
|
||||||
|
- 작업 완료 검증은 변경 범위 기준으로 선택한다.
|
||||||
|
- 필수 검증을 실행하지 못하면 차단 사유로 보고한다.
|
||||||
|
- 최종 보고에는 실행 명령, 결과, 생략 사유, 남은 위험을 남긴다.
|
||||||
|
- 환경값, secret, 개인 endpoint는 tracked docs/roadmap에 쓰지 않는다.
|
||||||
|
|
||||||
|
## 기본 환경
|
||||||
|
|
||||||
|
- host:
|
||||||
|
- port:
|
||||||
|
- runtime:
|
||||||
|
- package manager:
|
||||||
|
- docker:
|
||||||
|
- external service:
|
||||||
|
- model endpoint:
|
||||||
|
- credential:
|
||||||
|
|
||||||
|
## 라우팅
|
||||||
|
|
||||||
|
- 현재 등록된 도메인/검증 시나리오별 테스트 문서 없음.
|
||||||
|
|
||||||
|
## 라우팅 규칙
|
||||||
|
|
||||||
|
- 여러 항목이 맞으면 모두 읽는다.
|
||||||
|
- 도메인 매핑이나 domain rule이 있으면 각 도메인의 <domain>-smoke 문서를 기본 baseline으로 둔다.
|
||||||
|
- 도메인이 아직 없을 때만 project-smoke를 fallback baseline으로 둔다.
|
||||||
|
- 도메인/검증 시나리오별 문서는 다른 테스트 문서로 라우팅하지 않는다.
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
while IFS= read -r domain; do
|
||||||
|
[ -n "$domain" ] || continue
|
||||||
|
created_domain_profile="1"
|
||||||
|
ensure_agent_test_profile \
|
||||||
|
"$target_dir" \
|
||||||
|
"local" \
|
||||||
|
"$domain-smoke" \
|
||||||
|
"$domain" \
|
||||||
|
"smoke" \
|
||||||
|
"도메인 기본 smoke 검증" \
|
||||||
|
"$today"
|
||||||
|
done < <(discover_agent_test_domains "$target_dir" | sort -u)
|
||||||
|
|
||||||
|
if [ "$created_domain_profile" = "0" ]; then
|
||||||
|
ensure_agent_test_profile \
|
||||||
|
"$target_dir" \
|
||||||
|
"local" \
|
||||||
|
"project-smoke" \
|
||||||
|
"project-wide" \
|
||||||
|
"smoke" \
|
||||||
|
"프로젝트 기본 smoke 검증" \
|
||||||
|
"$today"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Initializing agent-ops in: $TARGET_DIR"
|
||||||
|
echo "Source agent-ops: $SOURCE_DIR"
|
||||||
|
|
||||||
|
# 1. 대상 폴더 생성 (프로젝트 전용 폴더는 내용 복사 없이 폴더만 생성)
|
||||||
|
create_project_agent_ops_dirs "$TARGET_DIR/agent-ops"
|
||||||
|
|
||||||
|
# 2. 공통 요소 복사 (프로젝트 전용 설정은 제외)
|
||||||
|
copy_common_agent_ops "$SOURCE_DIR" "$TARGET_DIR/agent-ops"
|
||||||
|
|
||||||
|
# 3. 에이전트 진입 파일 생성 (common/rules.md 복사)
|
||||||
|
COMMON_RULES="$SOURCE_DIR/rules/common/rules.md"
|
||||||
|
apply_agent_ops_entry_files "$COMMON_RULES" "$TARGET_DIR"
|
||||||
|
ensure_common_rules_file "$SOURCE_DIR" "$TARGET_DIR/agent-ops"
|
||||||
|
|
||||||
|
# 4. AI ignore / permission 설정
|
||||||
|
ensure_agent_ops_ai_ignore_config "$TARGET_DIR"
|
||||||
|
|
||||||
|
# 5. .gitignore 설정
|
||||||
|
TOUCH_GITIGNORE="$TARGET_DIR/.gitignore"
|
||||||
|
touch "$TOUCH_GITIGNORE"
|
||||||
|
agent_ops_ensure_gitignore_task_artifact_block "$TOUCH_GITIGNORE"
|
||||||
|
if ! grep -q "agent-ops/rules/private/" "$TOUCH_GITIGNORE"; then
|
||||||
|
echo "" >> "$TOUCH_GITIGNORE"
|
||||||
|
echo "# Agent-Ops Private Rules" >> "$TOUCH_GITIGNORE"
|
||||||
|
echo "agent-ops/rules/private/" >> "$TOUCH_GITIGNORE"
|
||||||
|
fi
|
||||||
|
if ! grep -qxF "# Agent-Test Local Environment" "$TOUCH_GITIGNORE"; then
|
||||||
|
echo "" >> "$TOUCH_GITIGNORE"
|
||||||
|
echo "# Agent-Test Local Environment" >> "$TOUCH_GITIGNORE"
|
||||||
|
fi
|
||||||
|
ensure_gitignore_entry "$TOUCH_GITIGNORE" "agent-test/local/"
|
||||||
|
ensure_gitignore_entry "$TOUCH_GITIGNORE" "agent-test/runs/"
|
||||||
|
|
||||||
|
# 6. local 테스트 환경 생성
|
||||||
|
ensure_agent_test_local "$TARGET_DIR"
|
||||||
|
|
||||||
|
echo "Successfully initialized agent-ops in $TARGET_DIR"
|
||||||
|
echo "Note: agent-ops/rules/project and agent-ops/skills/project are initialized as empty."
|
||||||
|
echo "Note: agent-test/local rules and baseline test profiles are initialized and ignored by git."
|
||||||
370
agent-ops/bin/roadmap-dependency-checker.sh
Executable file
370
agent-ops/bin/roadmap-dependency-checker.sh
Executable file
|
|
@ -0,0 +1,370 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
AGENT_OPS_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$AGENT_OPS_DIR/.." && pwd)"
|
||||||
|
WORKSPACE_ROOT="$(cd "$PROJECT_ROOT/.." && pwd)"
|
||||||
|
LOCKS_FILE="${AGENT_ROADMAP_LOCKS_FILE:-$WORKSPACE_ROOT/.agent-roadmap-sync/locks.yaml}"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
Usage: roadmap-dependency-checker.sh <lock-id> [locks.yaml]
|
||||||
|
roadmap-dependency-checker.sh --find-milestone <identity> [locked|rely-on|both] [locks.yaml]
|
||||||
|
|
||||||
|
Validates locked, rely-on.target, and rely-on.status for <lock-id>.
|
||||||
|
Prints true when every rely-on.status is enable.
|
||||||
|
Prints false when at least one rely-on.status is disable.
|
||||||
|
With --find-milestone, prints matching lock ids as locked:<id> or rely-on:<id>,
|
||||||
|
or none when the milestone identity is not referenced.
|
||||||
|
|
||||||
|
Exit codes:
|
||||||
|
0 all dependencies are enabled
|
||||||
|
1 at least one dependency is still disabled
|
||||||
|
2 configuration, input, or parse error
|
||||||
|
For --find-milestone, exit code 0 means the lookup completed; stdout is either
|
||||||
|
matching entries or none.
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
MODE="check"
|
||||||
|
LOCK_ID=""
|
||||||
|
FIND_IDENTITY=""
|
||||||
|
FIND_DIRECTION="both"
|
||||||
|
|
||||||
|
if [[ "${1:-}" == "--find-milestone" ]]; then
|
||||||
|
MODE="find"
|
||||||
|
if [[ $# -lt 2 || $# -gt 4 ]]; then
|
||||||
|
usage >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
FIND_IDENTITY="$2"
|
||||||
|
if [[ -z "$FIND_IDENTITY" ]]; then
|
||||||
|
echo "error: milestone identity is required" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
if [[ $# -ge 3 ]]; then
|
||||||
|
case "$3" in
|
||||||
|
locked|rely-on|both)
|
||||||
|
FIND_DIRECTION="$3"
|
||||||
|
if [[ $# -eq 4 ]]; then
|
||||||
|
LOCKS_FILE="$4"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if [[ $# -eq 3 ]]; then
|
||||||
|
LOCKS_FILE="$3"
|
||||||
|
else
|
||||||
|
usage >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
elif [[ $# -lt 1 || $# -gt 2 ]]; then
|
||||||
|
usage >&2
|
||||||
|
exit 2
|
||||||
|
else
|
||||||
|
LOCK_ID="$1"
|
||||||
|
if [[ -n "${2:-}" ]]; then
|
||||||
|
LOCKS_FILE="$2"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$MODE" == "check" && -z "$LOCK_ID" ]]; then
|
||||||
|
echo "error: lock id is required" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -r "$LOCKS_FILE" ]]; then
|
||||||
|
echo "error: locks file not readable: $LOCKS_FILE" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$MODE" == "find" ]]; then
|
||||||
|
awk -v identity="$FIND_IDENTITY" -v direction="$FIND_DIRECTION" '
|
||||||
|
function trim(value) {
|
||||||
|
gsub(/\r/, "", value)
|
||||||
|
sub(/^[[:space:]]+/, "", value)
|
||||||
|
sub(/[[:space:]]+$/, "", value)
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
function unquote(value) {
|
||||||
|
value = trim(value)
|
||||||
|
sub(/[[:space:]]+#.*$/, "", value)
|
||||||
|
value = trim(value)
|
||||||
|
if (value ~ /^".*"$/ || value ~ /^'\''.*'\''$/) {
|
||||||
|
return substr(value, 2, length(value) - 2)
|
||||||
|
}
|
||||||
|
return trim(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
function reset_entry() {
|
||||||
|
entry_id = ""
|
||||||
|
locked = ""
|
||||||
|
in_rely_on = 0
|
||||||
|
rely_count = 0
|
||||||
|
delete rely_targets
|
||||||
|
}
|
||||||
|
|
||||||
|
function finish_entry( i) {
|
||||||
|
if (entry_id == "") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ((direction == "both" || direction == "locked") && locked == identity) {
|
||||||
|
print "locked:" entry_id
|
||||||
|
found = 1
|
||||||
|
}
|
||||||
|
if (direction == "both" || direction == "rely-on") {
|
||||||
|
for (i = 1; i <= rely_count; i++) {
|
||||||
|
if (rely_targets[i] == identity) {
|
||||||
|
print "rely-on:" entry_id
|
||||||
|
found = 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BEGIN {
|
||||||
|
found = 0
|
||||||
|
reset_entry()
|
||||||
|
}
|
||||||
|
|
||||||
|
/^[[:space:]]*($|#)/ {
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
/^[[:space:]]*-[[:space:]]*id:[[:space:]]*/ {
|
||||||
|
finish_entry()
|
||||||
|
reset_entry()
|
||||||
|
value = $0
|
||||||
|
sub(/^[[:space:]]*-[[:space:]]*id:[[:space:]]*/, "", value)
|
||||||
|
entry_id = unquote(value)
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
entry_id != "" && /^[[:space:]]*locked:[[:space:]]*/ {
|
||||||
|
value = $0
|
||||||
|
sub(/^[[:space:]]*locked:[[:space:]]*/, "", value)
|
||||||
|
locked = unquote(value)
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
entry_id != "" && /^[[:space:]]*rely-on:[[:space:]]*/ {
|
||||||
|
in_rely_on = 1
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
entry_id != "" && in_rely_on && /^[[:space:]]*-[[:space:]]*target:[[:space:]]*/ {
|
||||||
|
value = $0
|
||||||
|
sub(/^[[:space:]]*-[[:space:]]*target:[[:space:]]*/, "", value)
|
||||||
|
rely_targets[++rely_count] = unquote(value)
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
entry_id != "" && in_rely_on && /^[[:space:]]*target:[[:space:]]*/ {
|
||||||
|
value = $0
|
||||||
|
sub(/^[[:space:]]*target:[[:space:]]*/, "", value)
|
||||||
|
rely_targets[++rely_count] = unquote(value)
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
END {
|
||||||
|
finish_entry()
|
||||||
|
if (!found) {
|
||||||
|
print "none"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
' "$LOCKS_FILE"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
awk -v wanted="$LOCK_ID" '
|
||||||
|
function trim(value) {
|
||||||
|
gsub(/\r/, "", value)
|
||||||
|
sub(/^[[:space:]]+/, "", value)
|
||||||
|
sub(/[[:space:]]+$/, "", value)
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
function unquote(value) {
|
||||||
|
value = trim(value)
|
||||||
|
sub(/[[:space:]]+#.*$/, "", value)
|
||||||
|
value = trim(value)
|
||||||
|
if (value ~ /^".*"$/ || value ~ /^'\''.*'\''$/) {
|
||||||
|
return substr(value, 2, length(value) - 2)
|
||||||
|
}
|
||||||
|
return trim(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
function fail(message) {
|
||||||
|
error = message
|
||||||
|
printf "error: %s\n", error > "/dev/stderr"
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
|
||||||
|
function finish_dependency() {
|
||||||
|
if (!selected || !in_dependency) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!dependency_has_target) {
|
||||||
|
fail("missing rely-on.target for lock id: " wanted)
|
||||||
|
}
|
||||||
|
if (!dependency_has_status) {
|
||||||
|
fail("missing rely-on.status for lock id: " wanted)
|
||||||
|
}
|
||||||
|
in_dependency = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function finish_entry() {
|
||||||
|
if (!selected) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
finish_dependency()
|
||||||
|
if (!entry_has_locked) {
|
||||||
|
fail("missing locked for lock id: " wanted)
|
||||||
|
}
|
||||||
|
if (total == 0) {
|
||||||
|
fail("no rely-on.status entries for lock id: " wanted)
|
||||||
|
}
|
||||||
|
selected = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
BEGIN {
|
||||||
|
selected = 0
|
||||||
|
matches = 0
|
||||||
|
total = 0
|
||||||
|
enabled = 0
|
||||||
|
error = ""
|
||||||
|
entry_has_locked = 0
|
||||||
|
in_rely_on = 0
|
||||||
|
in_dependency = 0
|
||||||
|
dependency_has_target = 0
|
||||||
|
dependency_has_status = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/^[[:space:]]*($|#)/ {
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
/^[[:space:]]*-[[:space:]]*id:[[:space:]]*/ {
|
||||||
|
finish_entry()
|
||||||
|
value = $0
|
||||||
|
sub(/^[[:space:]]*-[[:space:]]*id:[[:space:]]*/, "", value)
|
||||||
|
id = unquote(value)
|
||||||
|
if (id == wanted) {
|
||||||
|
if (matches > 0) {
|
||||||
|
fail("duplicate lock id: " wanted)
|
||||||
|
}
|
||||||
|
selected = 1
|
||||||
|
matches++
|
||||||
|
total = 0
|
||||||
|
enabled = 0
|
||||||
|
entry_has_locked = 0
|
||||||
|
in_rely_on = 0
|
||||||
|
in_dependency = 0
|
||||||
|
dependency_has_target = 0
|
||||||
|
dependency_has_status = 0
|
||||||
|
}
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
selected && /^[[:space:]]*locked:[[:space:]]*/ {
|
||||||
|
value = $0
|
||||||
|
sub(/^[[:space:]]*locked:[[:space:]]*/, "", value)
|
||||||
|
locked = unquote(value)
|
||||||
|
if (locked == "") {
|
||||||
|
fail("empty locked for lock id: " wanted)
|
||||||
|
}
|
||||||
|
entry_has_locked = 1
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
selected && /^[[:space:]]*rely-on:[[:space:]]*/ {
|
||||||
|
in_rely_on = 1
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
selected && in_rely_on && /^[[:space:]]*-[[:space:]]*target:[[:space:]]*/ {
|
||||||
|
finish_dependency()
|
||||||
|
in_dependency = 1
|
||||||
|
dependency_has_target = 0
|
||||||
|
dependency_has_status = 0
|
||||||
|
value = $0
|
||||||
|
sub(/^[[:space:]]*-[[:space:]]*target:[[:space:]]*/, "", value)
|
||||||
|
target = unquote(value)
|
||||||
|
if (target == "") {
|
||||||
|
fail("empty rely-on.target for lock id: " wanted)
|
||||||
|
}
|
||||||
|
dependency_has_target = 1
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
selected && in_rely_on && /^[[:space:]]*target:[[:space:]]*/ {
|
||||||
|
if (!in_dependency) {
|
||||||
|
fail("rely-on.target outside dependency item for lock id: " wanted)
|
||||||
|
}
|
||||||
|
value = $0
|
||||||
|
sub(/^[[:space:]]*target:[[:space:]]*/, "", value)
|
||||||
|
target = unquote(value)
|
||||||
|
if (target == "") {
|
||||||
|
fail("empty rely-on.target for lock id: " wanted)
|
||||||
|
}
|
||||||
|
dependency_has_target = 1
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
selected && in_rely_on && /^[[:space:]]*status:[[:space:]]*/ {
|
||||||
|
if (!in_dependency) {
|
||||||
|
fail("rely-on.status outside dependency item for lock id: " wanted)
|
||||||
|
}
|
||||||
|
value = $0
|
||||||
|
sub(/^[[:space:]]*status:[[:space:]]*/, "", value)
|
||||||
|
status = unquote(value)
|
||||||
|
if (status != "enable" && status != "disable") {
|
||||||
|
fail("invalid rely-on.status for " wanted ": " status)
|
||||||
|
}
|
||||||
|
if (dependency_has_status) {
|
||||||
|
fail("duplicate rely-on.status for lock id: " wanted)
|
||||||
|
}
|
||||||
|
dependency_has_status = 1
|
||||||
|
total++
|
||||||
|
if (status == "enable") {
|
||||||
|
enabled++
|
||||||
|
}
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
selected && in_rely_on && /^[[:space:]]*-[[:space:]]*/ {
|
||||||
|
finish_dependency()
|
||||||
|
fail("missing rely-on.target for lock id: " wanted)
|
||||||
|
}
|
||||||
|
|
||||||
|
selected && /^[[:space:]]*status:[[:space:]]*/ {
|
||||||
|
fail("status outside rely-on for lock id: " wanted)
|
||||||
|
}
|
||||||
|
|
||||||
|
END {
|
||||||
|
if (error != "") {
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
if (matches == 0) {
|
||||||
|
printf "error: lock id not found: %s\n", wanted > "/dev/stderr"
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
finish_entry()
|
||||||
|
if (total == enabled) {
|
||||||
|
print "true"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
print "false"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
' "$LOCKS_FILE"
|
||||||
375
agent-ops/bin/sync.sh
Executable file
375
agent-ops/bin/sync.sh
Executable file
|
|
@ -0,0 +1,375 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# ── 경로 설정 ────────────────────────────────────────────────────────────────
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
AGENT_OPS_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$AGENT_OPS_DIR/.." && pwd)"
|
||||||
|
|
||||||
|
# ── 색상 ─────────────────────────────────────────────────────────────────────
|
||||||
|
RED='\033[0;31m'; YELLOW='\033[1;33m'; GREEN='\033[0;32m'; RESET='\033[0m'
|
||||||
|
|
||||||
|
# ── 진입 파일 공통 관리 ──────────────────────────────────────────────────────
|
||||||
|
source "$SCRIPT_DIR/entry-files.sh"
|
||||||
|
source "$SCRIPT_DIR/ai-ignore.sh"
|
||||||
|
|
||||||
|
# ── 대상 경로 해석 (폴더명 / 상대경로 / 절대경로) ────────────────────────────
|
||||||
|
resolve_target() {
|
||||||
|
local input="$1"
|
||||||
|
if [[ "$input" == /* ]]; then
|
||||||
|
[[ -d "$input" ]] && echo "$input" || echo ""
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if [[ "$input" == */* ]]; then
|
||||||
|
local resolved
|
||||||
|
resolved="$(cd "$input" 2>/dev/null && pwd)" || { echo ""; return; }
|
||||||
|
echo "$resolved"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local sibling="$(dirname "$PROJECT_ROOT")/$input"
|
||||||
|
[[ -d "$sibling" ]] && echo "$sibling" || echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── 버전 비교: v1 > v2 이면 0 반환 ───────────────────────────────────────────
|
||||||
|
version_gt() {
|
||||||
|
local v1="$1" v2="$2"
|
||||||
|
[[ "$v1" == "$v2" ]] && return 1
|
||||||
|
[[ "$(printf '%s\n%s' "$v1" "$v2" | sort -V | head -1)" == "$v2" ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── 버전 +1 ──────────────────────────────────────────────────────────────────
|
||||||
|
bump_version() {
|
||||||
|
bash "$SCRIPT_DIR/bump-version.sh" "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── 폴더 동기화 (삭제된 파일도 반영) ────────────────────────────────────────
|
||||||
|
sync_folder() {
|
||||||
|
local src="$1" dst="$2" exclude="${3:-}"
|
||||||
|
mkdir -p "$dst"
|
||||||
|
# dst에서 src에 없는 항목 제거 (exclude 파일 보존)
|
||||||
|
find "$dst" -mindepth 1 -maxdepth 1 | while IFS= read -r item; do
|
||||||
|
local name
|
||||||
|
name="$(basename "$item")"
|
||||||
|
[[ -n "$exclude" && "$name" == "$exclude" ]] && continue
|
||||||
|
if [[ ! -e "$src/$name" ]]; then
|
||||||
|
rm -rf "$item"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
# src에서 dst로 복사 (exclude 파일 제외)
|
||||||
|
find "$src" -mindepth 1 -maxdepth 1 | while IFS= read -r item; do
|
||||||
|
local name
|
||||||
|
name="$(basename "$item")"
|
||||||
|
[[ -n "$exclude" && "$name" == "$exclude" ]] && continue
|
||||||
|
rm -rf "$dst/$name"
|
||||||
|
cp -r "$item" "$dst/"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
sync_common() {
|
||||||
|
local src="$1" dst="$2"
|
||||||
|
sync_folder "$src/rules/common" "$dst/rules/common"
|
||||||
|
sync_folder "$src/skills/common" "$dst/skills/common"
|
||||||
|
sync_folder "$src/bin" "$dst/bin"
|
||||||
|
}
|
||||||
|
|
||||||
|
common_differs() {
|
||||||
|
local src="$1" dst="$2"
|
||||||
|
local path
|
||||||
|
|
||||||
|
for path in "rules/common" "skills/common" "bin"; do
|
||||||
|
if [[ ! -d "$src/$path" || ! -d "$dst/$path" ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if ! diff -qr "$src/$path" "$dst/$path" >/dev/null; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
entry_files_differ() {
|
||||||
|
local rules_md="$1" target_root="$2"
|
||||||
|
local f
|
||||||
|
|
||||||
|
[[ -f "$rules_md" ]] || return 0
|
||||||
|
for f in "${AGENT_OPS_ENTRY_FILES[@]}"; do
|
||||||
|
if [[ ! -f "$target_root/$f" ]] || ! cmp -s "$rules_md" "$target_root/$f"; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
create_project_agent_ops_dirs() {
|
||||||
|
local agent_ops_dir="$1"
|
||||||
|
mkdir -p "$agent_ops_dir/rules/project/domain"
|
||||||
|
mkdir -p "$agent_ops_dir/rules/private"
|
||||||
|
mkdir -p "$agent_ops_dir/skills/project"
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_common_scaffold() {
|
||||||
|
local src="$1" dst="$2"
|
||||||
|
mkdir -p "$dst/rules" "$dst/skills"
|
||||||
|
cp "$src/.version" "$dst/"
|
||||||
|
rm -rf "$dst/bin" "$dst/rules/common" "$dst/skills/common"
|
||||||
|
cp -r "$src/bin" "$dst/"
|
||||||
|
cp -r "$src/rules/common" "$dst/rules/"
|
||||||
|
cp -r "$src/skills/common" "$dst/skills/"
|
||||||
|
create_project_agent_ops_dirs "$dst"
|
||||||
|
}
|
||||||
|
|
||||||
|
discover_agent_ops_targets() {
|
||||||
|
local parent
|
||||||
|
parent="$(dirname "$PROJECT_ROOT")"
|
||||||
|
|
||||||
|
find "$parent" -mindepth 1 -maxdepth 1 -type d | sort | while IFS= read -r candidate; do
|
||||||
|
local resolved
|
||||||
|
resolved="$(cd "$candidate" && pwd)"
|
||||||
|
[[ "$resolved" == "$PROJECT_ROOT" ]] && continue
|
||||||
|
[[ -d "$resolved/agent-ops" ]] || continue
|
||||||
|
echo "$resolved"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
agent_ops_git_paths() {
|
||||||
|
local include_ai_config="${1:-1}"
|
||||||
|
|
||||||
|
printf '%s\n' "agent-ops/.version"
|
||||||
|
printf '%s\n' "agent-ops/bin"
|
||||||
|
printf '%s\n' "agent-ops/rules/common"
|
||||||
|
printf '%s\n' "agent-ops/skills/common"
|
||||||
|
|
||||||
|
local f
|
||||||
|
for f in "${AGENT_OPS_ENTRY_FILES[@]}"; do
|
||||||
|
if [[ -e "$f" ]] || git ls-files --error-unmatch "$f" >/dev/null 2>&1; then
|
||||||
|
printf '%s\n' "$f"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ "$include_ai_config" != "1" || -f ".agent-ops-source" ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
for f in "${AGENT_OPS_AI_SYNC_FILES[@]}"; do
|
||||||
|
if [[ -e "$f" ]] || git ls-files --error-unmatch "$f" >/dev/null 2>&1; then
|
||||||
|
printf '%s\n' "$f"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
commit_and_push_agent_ops_scope() {
|
||||||
|
local repo="$1" message="$2"
|
||||||
|
local include_ai_config="${3:-1}"
|
||||||
|
|
||||||
|
if ! git -C "$repo" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||||
|
echo -e "${RED}Error: git 저장소가 아닙니다: $repo${RESET}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
(
|
||||||
|
cd "$repo"
|
||||||
|
mapfile -t paths < <(agent_ops_git_paths "$include_ai_config")
|
||||||
|
git add -- "${paths[@]}"
|
||||||
|
if git ls-files --error-unmatch "$AGENT_ROADMAP_CURRENT_LOCAL_PATTERN" >/dev/null 2>&1 \
|
||||||
|
&& grep -qxF "$AGENT_ROADMAP_CURRENT_LOCAL_PATTERN" ".gitignore" 2>/dev/null; then
|
||||||
|
git rm --cached --quiet --ignore-unmatch "$AGENT_ROADMAP_CURRENT_LOCAL_PATTERN"
|
||||||
|
paths+=("$AGENT_ROADMAP_CURRENT_LOCAL_PATTERN")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if git diff --cached --quiet -- "${paths[@]}"; then
|
||||||
|
echo " agent-ops 변경 없음: commit 건너뜀"
|
||||||
|
else
|
||||||
|
git commit -m "$message" -- "${paths[@]}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
git push
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
sync_framework_to_target() {
|
||||||
|
local target="$1"
|
||||||
|
local dst_ao="$target/agent-ops"
|
||||||
|
local src_ver
|
||||||
|
src_ver="$(cat "$SRC_AO/.version" 2>/dev/null || echo "0.0.0")"
|
||||||
|
|
||||||
|
echo "▶ $(basename "$PROJECT_ROOT") → $(basename "$target")"
|
||||||
|
|
||||||
|
if ! git -C "$target" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||||
|
echo -e "${RED}Error: git 저장소가 아닙니다: $target${RESET}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -d "$dst_ao" ]]; then
|
||||||
|
echo " 최초 진행: agent-ops 공통 scaffold 복사"
|
||||||
|
copy_common_scaffold "$SRC_AO" "$dst_ao"
|
||||||
|
apply_agent_ops_entry_files "$SRC_AO/rules/common/rules.md" "$target"
|
||||||
|
echo -e "${YELLOW} init-agent-ops 스킬로 초기화를 진행하세요.${RESET}"
|
||||||
|
else
|
||||||
|
echo " 이후 진행: common/ 동기화"
|
||||||
|
sync_common "$SRC_AO" "$dst_ao"
|
||||||
|
cp "$SRC_AO/.version" "$dst_ao/.version"
|
||||||
|
apply_agent_ops_entry_files "$SRC_AO/rules/common/rules.md" "$target"
|
||||||
|
fi
|
||||||
|
ensure_agent_ops_ai_ignore_config "$target"
|
||||||
|
|
||||||
|
commit_and_push_agent_ops_scope "$target" "sync: agent-ops from $(basename "$PROJECT_ROOT") v$src_ver"
|
||||||
|
echo -e "${GREEN}✓ 완료 → $(basename "$target")${RESET}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── 사용법 ────────────────────────────────────────────────────────────────────
|
||||||
|
usage() {
|
||||||
|
echo "사용법: $0 [--pull] [target]"
|
||||||
|
echo ""
|
||||||
|
echo " (기본) push 동기화"
|
||||||
|
echo " --pull target(공통 원본 repo, 기본 agentic-framework) → 현재 프로젝트 로 pull"
|
||||||
|
echo ""
|
||||||
|
echo " target: 폴더명 (동일 레벨 탐색) | 상대경로 | 절대경로"
|
||||||
|
echo " .agent-ops-source 원본 repo에서 target 생략 시 상위 폴더의 agent-ops 적용 프로젝트 전체 동기화"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
PULL_MODE="0"
|
||||||
|
if [[ "${1:-}" == "--pull" ]]; then
|
||||||
|
PULL_MODE="1"
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
TARGET_INPUT="${1:-}"
|
||||||
|
|
||||||
|
SRC_AO="$AGENT_OPS_DIR"
|
||||||
|
IS_FRAMEWORK="$([[ -f "$PROJECT_ROOT/.agent-ops-source" ]] && echo "1" || echo "0")"
|
||||||
|
|
||||||
|
# ── pull 모드: .agent-ops-source 원본 repo → 현재 프로젝트 ───────────────────
|
||||||
|
if [[ "$PULL_MODE" == "1" ]]; then
|
||||||
|
if [[ -z "$TARGET_INPUT" ]]; then
|
||||||
|
usage; exit 1
|
||||||
|
fi
|
||||||
|
TARGET="$(resolve_target "$TARGET_INPUT")"
|
||||||
|
if [[ -z "$TARGET" ]]; then
|
||||||
|
echo -e "${RED}Error: 대상을 찾을 수 없습니다: $TARGET_INPUT${RESET}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
DST_AO="$TARGET/agent-ops"
|
||||||
|
|
||||||
|
if [[ "$IS_FRAMEWORK" == "1" ]]; then
|
||||||
|
echo -e "${RED}Error: .agent-ops-source가 있는 공통 원본 repo에서는 --pull을 사용할 수 없습니다.${RESET}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ ! -f "$TARGET/.agent-ops-source" ]]; then
|
||||||
|
echo -e "${RED}Error: target이 공통 원본 repo가 아닙니다 (.agent-ops-source 없음)${RESET}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
SRC_VER="$(cat "$SRC_AO/.version" 2>/dev/null || echo "0.0.0")"
|
||||||
|
DST_VER="$(cat "$DST_AO/.version" 2>/dev/null || echo "0.0.0")"
|
||||||
|
echo "▶ $(basename "$TARGET") → $(basename "$PROJECT_ROOT") (pull)"
|
||||||
|
echo " 현재 버전: $SRC_VER | 원본 버전: $DST_VER"
|
||||||
|
sync_common "$DST_AO" "$SRC_AO"
|
||||||
|
cp "$DST_AO/.version" "$SRC_AO/.version"
|
||||||
|
apply_agent_ops_entry_files "$DST_AO/rules/common/rules.md" "$PROJECT_ROOT"
|
||||||
|
ensure_agent_ops_ai_ignore_config "$PROJECT_ROOT"
|
||||||
|
commit_and_push_agent_ops_scope "$PROJECT_ROOT" "sync: pull from agentic-framework v$DST_VER"
|
||||||
|
echo -e "${GREEN}✓ 완료 (pull v$DST_VER)${RESET}"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── .agent-ops-source 원본 repo에서 다른 프로젝트로 ──────────────────────────
|
||||||
|
if [[ "$IS_FRAMEWORK" == "1" ]]; then
|
||||||
|
SRC_VER="$(cat "$SRC_AO/.version" 2>/dev/null || echo "0.0.0")"
|
||||||
|
echo " .agent-ops-source 감지: push 동기화에서는 버전 bump 없이 v$SRC_VER 그대로 전파"
|
||||||
|
if entry_files_differ "$SRC_AO/rules/common/rules.md" "$PROJECT_ROOT"; then
|
||||||
|
echo " 공통 원본 repo 진입 파일 재적용"
|
||||||
|
apply_agent_ops_entry_files "$SRC_AO/rules/common/rules.md" "$PROJECT_ROOT"
|
||||||
|
commit_and_push_agent_ops_scope "$PROJECT_ROOT" "sync: reapply agent-ops entry files" "0"
|
||||||
|
fi
|
||||||
|
if [[ -n "$TARGET_INPUT" ]]; then
|
||||||
|
TARGET="$(resolve_target "$TARGET_INPUT")"
|
||||||
|
if [[ -z "$TARGET" ]]; then
|
||||||
|
echo -e "${RED}Error: 대상을 찾을 수 없습니다: $TARGET_INPUT${RESET}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sync_framework_to_target "$TARGET"
|
||||||
|
else
|
||||||
|
mapfile -t TARGETS < <(discover_agent_ops_targets)
|
||||||
|
if [[ "${#TARGETS[@]}" -eq 0 ]]; then
|
||||||
|
echo -e "${YELLOW}agent-ops가 적용된 sibling 프로젝트가 없습니다.${RESET}"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
STATUS=0
|
||||||
|
for TARGET in "${TARGETS[@]}"; do
|
||||||
|
if ! sync_framework_to_target "$TARGET"; then
|
||||||
|
STATUS=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
exit "$STATUS"
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 일반 프로젝트에서 .agent-ops-source 원본 repo로 (push) ───────────────────
|
||||||
|
if [[ -z "$TARGET_INPUT" ]]; then
|
||||||
|
TARGET_INPUT="agentic-framework"
|
||||||
|
fi
|
||||||
|
|
||||||
|
TARGET="$(resolve_target "$TARGET_INPUT")"
|
||||||
|
if [[ -z "$TARGET" ]]; then
|
||||||
|
echo -e "${RED}Error: 대상을 찾을 수 없습니다: $TARGET_INPUT${RESET}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
DST_AO="$TARGET/agent-ops"
|
||||||
|
|
||||||
|
echo "▶ $(basename "$PROJECT_ROOT") → $(basename "$TARGET")"
|
||||||
|
|
||||||
|
if [[ ! -f "$TARGET/.agent-ops-source" ]]; then
|
||||||
|
echo -e "${RED}Error: target이 공통 원본 repo가 아닙니다 (.agent-ops-source 없음)${RESET}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
SRC_VER="$(cat "$SRC_AO/.version" 2>/dev/null || echo "0.0.0")"
|
||||||
|
DST_VER="$(cat "$DST_AO/.version" 2>/dev/null || echo "0.0.0")"
|
||||||
|
echo " 현재 버전: $SRC_VER | 원본 버전: $DST_VER"
|
||||||
|
|
||||||
|
COMMON_CHANGED="1"
|
||||||
|
if ! common_differs "$SRC_AO" "$DST_AO"; then
|
||||||
|
COMMON_CHANGED="0"
|
||||||
|
fi
|
||||||
|
|
||||||
|
ENTRY_FILES_CHANGED="0"
|
||||||
|
if entry_files_differ "$SRC_AO/rules/common/rules.md" "$PROJECT_ROOT" \
|
||||||
|
|| entry_files_differ "$DST_AO/rules/common/rules.md" "$TARGET"; then
|
||||||
|
ENTRY_FILES_CHANGED="1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$COMMON_CHANGED" == "1" ]] && version_gt "$DST_VER" "$SRC_VER"; then
|
||||||
|
echo -e "${RED}⚠ 버전 충돌: 원본 repo($DST_VER) > current($SRC_VER)${RESET}"
|
||||||
|
echo -e "${YELLOW} 먼저 sync-pull로 내려받은 뒤 재시도하세요.${RESET}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$COMMON_CHANGED" == "0" && "$ENTRY_FILES_CHANGED" == "0" ]]; then
|
||||||
|
echo " 공통 파일/진입 파일 변경 없음: .version 차이는 무시하고 버전 갱신/커밋을 건너뜀"
|
||||||
|
echo -e "${GREEN}✓ 완료 (공통 변경 없음)${RESET}"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$COMMON_CHANGED" == "0" ]]; then
|
||||||
|
echo " 공통 파일 변경 없음: 진입 파일만 재적용"
|
||||||
|
apply_agent_ops_entry_files "$SRC_AO/rules/common/rules.md" "$PROJECT_ROOT"
|
||||||
|
apply_agent_ops_entry_files "$DST_AO/rules/common/rules.md" "$TARGET"
|
||||||
|
commit_and_push_agent_ops_scope "$TARGET" "sync: reapply agent-ops entry files" "0"
|
||||||
|
commit_and_push_agent_ops_scope "$PROJECT_ROOT" "sync: reapply agent-ops entry files" "0"
|
||||||
|
echo -e "${GREEN}✓ 완료 (진입 파일 재적용)${RESET}"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
NEW_VER="$(bump_version "$SRC_VER")"
|
||||||
|
sync_common "$SRC_AO" "$DST_AO"
|
||||||
|
echo "$NEW_VER" > "$SRC_AO/.version"
|
||||||
|
echo "$NEW_VER" > "$DST_AO/.version"
|
||||||
|
apply_agent_ops_entry_files "$SRC_AO/rules/common/rules.md" "$PROJECT_ROOT"
|
||||||
|
apply_agent_ops_entry_files "$DST_AO/rules/common/rules.md" "$TARGET"
|
||||||
|
|
||||||
|
commit_and_push_agent_ops_scope "$TARGET" "sync: from $(basename "$PROJECT_ROOT") v$NEW_VER" "0"
|
||||||
|
commit_and_push_agent_ops_scope "$PROJECT_ROOT" "sync: to agentic-framework v$NEW_VER" "0"
|
||||||
|
|
||||||
|
echo -e "${GREEN}✓ 완료 (v$SRC_VER → v$NEW_VER)${RESET}"
|
||||||
35
agent-ops/rules/common/_templates/domain-rule-template.md
Normal file
35
agent-ops/rules/common/_templates/domain-rule-template.md
Normal 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>**: <어디까지가 이 도메인이고 어디서부터 저 도메인인지>
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- <이 도메인 코드에서 하면 안 되는 것>
|
||||||
79
agent-ops/rules/common/_templates/test-case-rule-template.md
Normal file
79
agent-ops/rules/common/_templates/test-case-rule-template.md
Normal 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 파일에 기록하지 않는다.
|
||||||
43
agent-ops/rules/common/_templates/test-env-rules-template.md
Normal file
43
agent-ops/rules/common/_templates/test-env-rules-template.md
Normal 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으로 둔다.
|
||||||
|
- 도메인/검증 시나리오별 문서는 다른 테스트 문서로 라우팅하지 않는다.
|
||||||
98
agent-ops/rules/common/philosophy.md
Normal file
98
agent-ops/rules/common/philosophy.md
Normal 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이 파일명만 봐도 될 일을 본문까지 읽어 판단하고 있다.
|
||||||
108
agent-ops/rules/common/rules-agent-spec.md
Normal file
108
agent-ops/rules/common/rules-agent-spec.md
Normal 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`
|
||||||
161
agent-ops/rules/common/rules-agent-ui.md
Normal file
161
agent-ops/rules/common/rules-agent-ui.md
Normal 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`를 사용한다.
|
||||||
205
agent-ops/rules/common/rules-roadmap.md
Normal file
205
agent-ops/rules/common/rules-roadmap.md
Normal 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 선택이나 위치 분석의 후보로 삼지 않는다.
|
||||||
|
- 아카이브 문서는 과거 기록 스냅샷으로 보고, 최신 템플릿이나 스킬 규약에 맞춰 재포맷하지 않는다.
|
||||||
55
agent-ops/rules/common/rules.md
Normal file
55
agent-ops/rules/common/rules.md
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
# 공통 규칙
|
||||||
|
|
||||||
|
**현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
|
||||||
|
|
||||||
|
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
|
||||||
|
- `agent-ops/rules/common/**`와 `agent-ops/skills/common/**`은 중앙 관리되는 공통 영역이므로 어떤 프로젝트 작업에서도 사용자가 직접 지시하지 않는 이상 절대 직접 수정하지 않는다. 프로젝트별 규칙과 스킬은 반드시 대응하는 `project/**` 영역에만 반영한다.
|
||||||
|
- 최종 답변은 한국어로 한다.
|
||||||
|
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
|
||||||
|
- 요청 범위를 넘는 변경을 하지 않는다.
|
||||||
|
- 불확실하면 단정하지 말고 후보를 제시한다.
|
||||||
|
- `agent-task/archive/**`는 일반 작업에서 읽지 않는다. 예외: 사용자가 과거 작업 확인, 복원, 비교, 특정 archive 경로 확인을 요청한 경우, active `PLAN-*.md` / `CODE_REVIEW-*.md` / `USER_REVIEW.md`가 특정 archive evidence 경로를 명시한 경우, 또는 plan/code-review 루프의 split subtask 선행 의존성 충족 여부를 확인하는 경우에만 필요한 파일을 좁게 읽는다. 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`)
|
||||||
52
agent-ops/rules/project/domain/client/rules.md
Normal file
52
agent-ops/rules/project/domain/client/rules.md
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
---
|
||||||
|
domain: client
|
||||||
|
last_rule_review_commit: unborn-head
|
||||||
|
last_rule_updated_at: 2026-07-23
|
||||||
|
---
|
||||||
|
|
||||||
|
# client
|
||||||
|
|
||||||
|
## 목적 / 책임
|
||||||
|
|
||||||
|
Ariadne의 조직 범위 오류, 프로젝트, 수정 작업, 검토 상태를 한국어 Flutter 웹 화면으로 제공하며 서버·IOP 권한 판정과 분리된 사용자 경험을 유지한다.
|
||||||
|
|
||||||
|
## 포함 경로
|
||||||
|
|
||||||
|
- `apps/client/lib/` — 애플리케이션, 기능 화면, 공유 테마의 Dart 코드다.
|
||||||
|
- `apps/client/test/` — Flutter 위젯과 사용자 화면 동작 검증이다.
|
||||||
|
- `apps/client/web/` — Flutter 웹 엔트리와 정적 자산이다.
|
||||||
|
- `apps/client/pubspec.yaml` — Dart SDK와 Flutter 의존성 기준이다.
|
||||||
|
- `.fvmrc` — 프로젝트 Flutter SDK 버전 기준이다.
|
||||||
|
|
||||||
|
## 제외 경로
|
||||||
|
|
||||||
|
- `internal/domain/` — 조직·오류·수정 작업의 권한과 상태 판정은 domain-model 책임이다.
|
||||||
|
- `internal/platform/httpserver/` — API 라우팅과 서버 수명주기는 platform 책임이다.
|
||||||
|
- `internal/integration/iop/` — IOP 실행과 이벤트 스트림은 integrations 책임이다.
|
||||||
|
|
||||||
|
## 주요 구성 요소
|
||||||
|
|
||||||
|
- `AriadneApp` — 한국어 locale과 Material 3 테마를 적용하는 앱 루트다.
|
||||||
|
- `OverviewPage` — 화면 너비에 따라 rail과 drawer를 전환하는 반응형 개요 화면이다.
|
||||||
|
- `AppTheme` — Ariadne의 색상, 타이포그래피, 카드 스타일을 모은 공유 테마다.
|
||||||
|
|
||||||
|
## 유지할 패턴
|
||||||
|
|
||||||
|
- 기능 화면은 `lib/features/`, 공통 시각 요소는 `lib/shared/` 경계를 유지한다.
|
||||||
|
- 가능한 위젯과 값은 `const`로 선언하고 `flutter_lints` 기준을 따른다.
|
||||||
|
- Material 3와 한국어 locale을 유지하며 좁은 화면에서도 조직·탐색 의미가 보존되게 한다.
|
||||||
|
- 아직 연결되지 않은 기능은 활성 동작처럼 보이게 하지 말고 tooltip·semantics로 준비 중 상태를 명확히 한다.
|
||||||
|
- 화면 추가 시 widget test와 `flutter analyze` 검증을 함께 갱신한다.
|
||||||
|
|
||||||
|
## 다른 도메인과의 경계
|
||||||
|
|
||||||
|
- **domain-model**: 서버가 제공한 조직 범위 상태를 표현하되 클라이언트에서 권한이나 수정 가능성을 최종 판정하지 않는다.
|
||||||
|
- **integrations**: IOP 연결 상태를 표시할 수 있지만 IOP endpoint나 자격 증명을 직접 다루지 않는다.
|
||||||
|
- **platform**: Ariadne API를 통해 통신하며 데이터베이스나 서버 내부 타입에 직접 의존하지 않는다.
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- 클라이언트가 요청 본문의 조직 식별자만으로 접근 범위를 결정하도록 만들지 않는다.
|
||||||
|
- IOP, PostgreSQL, 운영 환경에 직접 연결하거나 비밀값을 Flutter 자산에 포함하지 않는다.
|
||||||
|
- 미구현 탐색 항목과 조직 선택 UI에 실제 동작이 있는 것처럼 오해시키는 상호작용을 추가하지 않는다.
|
||||||
|
- 로컬 형제 저장소의 Dart 패키지를 정식 의존성으로 추가하지 않는다.
|
||||||
51
agent-ops/rules/project/domain/domain-model/rules.md
Normal file
51
agent-ops/rules/project/domain/domain-model/rules.md
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
---
|
||||||
|
domain: domain-model
|
||||||
|
last_rule_review_commit: unborn-head
|
||||||
|
last_rule_updated_at: 2026-07-23
|
||||||
|
---
|
||||||
|
|
||||||
|
# domain-model
|
||||||
|
|
||||||
|
## 목적 / 책임
|
||||||
|
|
||||||
|
인증된 범위가 결합된 오류 이벤트, 조직 식별자, 표준 실패 원인, 수정 방식과 수정 가능성 등 Ariadne의 핵심 불변 규칙을 정의한다.
|
||||||
|
|
||||||
|
## 포함 경로
|
||||||
|
|
||||||
|
- `internal/domain/errorrecord/` — 입력 오류를 Ariadne 내부의 조직·프로젝트 범위가 결합된 이벤트로 정규화한다.
|
||||||
|
- `internal/domain/organization/` — 조직 범위에 사용하는 검증 가능한 식별자 타입을 제공한다.
|
||||||
|
- `internal/domain/failure/` — 오류 처리 단계와 중첩 원인을 포함한 표준 실패 모델을 제공한다.
|
||||||
|
- `internal/domain/remediation/` — 수정 전 보고·자동 수정 후 보고 방식과 수정 가능성 값을 정의한다.
|
||||||
|
|
||||||
|
## 제외 경로
|
||||||
|
|
||||||
|
- `internal/platform/database/` — 도메인 모델의 PostgreSQL 저장·격리 구현은 platform 책임이다.
|
||||||
|
- `internal/integration/iop/` — IOP 요청과 이벤트 변환은 integrations 책임이다.
|
||||||
|
- `contracts/` — 외부 wire schema와 버전 관리는 integrations 책임이다.
|
||||||
|
|
||||||
|
## 주요 구성 요소
|
||||||
|
|
||||||
|
- `errorrecord.Event` — 인증된 입력 출처에서 결정한 조직·프로젝트 범위를 포함하는 정규화 오류다.
|
||||||
|
- `organization.ID` — UUID 기반 조직 식별자 값 타입이다.
|
||||||
|
- `failure.Failure`, `failure.Cause` — 처리 단계, 재시도 가능성, 원인 스택을 표현한다.
|
||||||
|
- `remediation.Mode`, `remediation.Fixability` — 수정 작업 방식과 분석 결과의 수정 가능성을 제한된 값으로 표현한다.
|
||||||
|
|
||||||
|
## 유지할 패턴
|
||||||
|
|
||||||
|
- 외부 계약과 연결되는 값은 `SchemaVersionV1` 같은 명시적 버전 상수를 유지한다.
|
||||||
|
- 값 검증은 각 타입의 `Validate` 또는 `Parse...` 경계에서 수행하고 여러 오류는 `errors.Join`으로 함께 반환한다.
|
||||||
|
- `errorrecord.Event`의 조직, 프로젝트, 입력 출처는 인증된 자격 증명 해석 결과로 주입한다.
|
||||||
|
- 실패 단계와 수정 방식은 닫힌 열거 값으로 유지하고 알 수 없는 값을 거부한다.
|
||||||
|
|
||||||
|
## 다른 도메인과의 경계
|
||||||
|
|
||||||
|
- **integrations**: 도메인 타입을 IOP·JSON 계약에 연결하되 외부 전송 형식을 이 도메인으로 역류시키지 않는다.
|
||||||
|
- **platform**: 도메인 타입의 저장과 조직 격리를 담당하지만 도메인 불변 규칙을 SQL에만 숨기지 않는다.
|
||||||
|
- **client**: 사용자에게 상태를 표현하되 도메인 판정과 권한 결정을 화면 코드에서 수행하지 않는다.
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- 요청 본문의 조직·프로젝트 식별자를 신뢰해 `errorrecord.Event` 범위를 결정하지 않는다.
|
||||||
|
- 도메인 패키지에서 pgx, HTTP, IOP 네이티브 프로토콜에 직접 의존하지 않는다.
|
||||||
|
- `Fixability`에 승인 상태나 실행 상태를 섞지 않는다.
|
||||||
|
- 기존 표준 실패 단계나 schema version을 호환성 검토 없이 변경하지 않는다.
|
||||||
53
agent-ops/rules/project/domain/integrations/rules.md
Normal file
53
agent-ops/rules/project/domain/integrations/rules.md
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
---
|
||||||
|
domain: integrations
|
||||||
|
last_rule_review_commit: unborn-head
|
||||||
|
last_rule_updated_at: 2026-07-23
|
||||||
|
---
|
||||||
|
|
||||||
|
# integrations
|
||||||
|
|
||||||
|
## 목적 / 책임
|
||||||
|
|
||||||
|
Ariadne가 소유하는 외부 오류 입력과 IOP 실행 경계를 버전 계약으로 정의하고, 외부 실행 계층이 도메인·권한 경계를 침범하지 못하도록 요청과 이벤트를 검증한다.
|
||||||
|
|
||||||
|
## 포함 경로
|
||||||
|
|
||||||
|
- `internal/integration/iop/` — LLM·CLI 작업의 실행, 이벤트 스트림, 취소를 위한 Ariadne 소유 인터페이스다.
|
||||||
|
- `contracts/error-event/` — 외부 시스템이 전송하는 오류 이벤트 JSON Schema다.
|
||||||
|
- `contracts/execution-failure/` — 처리 실패 원인 스택의 JSON Schema다.
|
||||||
|
- `contracts/iop-execution/` — IOP 실행 요청과 상태 이벤트의 버전별 JSON Schema다.
|
||||||
|
|
||||||
|
## 제외 경로
|
||||||
|
|
||||||
|
- `internal/domain/` — 오류와 수정 작업의 내부 의미와 불변 규칙은 domain-model 책임이다.
|
||||||
|
- `internal/platform/httpserver/` — Ariadne HTTP 프로세스의 수명주기와 라우팅은 platform 책임이다.
|
||||||
|
- `internal/platform/database/` — 계약 데이터의 영속화와 조직 격리는 platform 책임이다.
|
||||||
|
|
||||||
|
## 주요 구성 요소
|
||||||
|
|
||||||
|
- `iop.Executor` — 실행 시작, 조직 범위 이벤트 조회, 취소를 추상화한 Ariadne 소유 포트다.
|
||||||
|
- `iop.Request` — 오류, 저장소, 읽기 전용 실행 환경, 실행 정책과 deadline을 묶는 요청이다.
|
||||||
|
- `iop.Event` — 순서 번호와 단일 타입별 payload를 갖는 실행 이벤트다.
|
||||||
|
- `contracts/*/v1/*.json` — 외부 wire format의 v1 기준 문서다.
|
||||||
|
|
||||||
|
## 유지할 패턴
|
||||||
|
|
||||||
|
- 계약은 버전 디렉터리와 `schema_version`을 함께 사용하고 기존 버전을 제자리에서 깨지 않는다.
|
||||||
|
- `Request.Validate`에서 조직·프로젝트·입력 출처 범위가 오류 이벤트 범위와 일치하는지 확인한다.
|
||||||
|
- 분석 요청은 읽기 전용 저장소 접근만, 변경 요청은 격리된 작업 가지 접근만 허용한다.
|
||||||
|
- 실행 환경은 항상 읽기 전용이고 `AllowMerge`는 항상 거부한다.
|
||||||
|
- 변경 요청은 승인 또는 정책이 허용한 `ProposalDigest`를 요구하고 분석 요청에는 digest를 넣지 않는다.
|
||||||
|
- 이벤트 타입별 payload는 정확히 하나만 허용하며 실패 payload는 domain-model의 표준 실패 검증을 통과해야 한다.
|
||||||
|
|
||||||
|
## 다른 도메인과의 경계
|
||||||
|
|
||||||
|
- **domain-model**: 내부 의미와 닫힌 값 집합을 재사용하되 IOP 네이티브 형식을 도메인 타입으로 만들지 않는다.
|
||||||
|
- **platform**: HTTP·설정·데이터베이스 어댑터가 이 포트를 조립하며 integrations는 원시 연결 풀을 소유하지 않는다.
|
||||||
|
- **client**: 화면에 필요한 상태는 Ariadne API를 통해 제공하고 클라이언트가 IOP에 직접 연결하지 않는다.
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- 조직 식별자, 비밀값, endpoint를 입력 본문이나 LLM payload의 임의 값으로 신뢰하지 않는다.
|
||||||
|
- IOP에 운영 환경 쓰기 권한이나 직접 병합 권한을 표현하거나 전달하지 않는다.
|
||||||
|
- 분석 요청에 격리 가지 쓰기 권한을 주거나 변경 요청을 기본 가지에서 실행하지 않는다.
|
||||||
|
- 계약 변경과 Go 경계 타입 변경을 서로 검증하지 않은 채 따로 반영하지 않는다.
|
||||||
56
agent-ops/rules/project/domain/platform/rules.md
Normal file
56
agent-ops/rules/project/domain/platform/rules.md
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
---
|
||||||
|
domain: platform
|
||||||
|
last_rule_review_commit: unborn-head
|
||||||
|
last_rule_updated_at: 2026-07-23
|
||||||
|
---
|
||||||
|
|
||||||
|
# platform
|
||||||
|
|
||||||
|
## 목적 / 책임
|
||||||
|
|
||||||
|
Go 서버와 마이그레이션 프로세스를 조립하고, 설정·로깅·HTTP·PostgreSQL 연결 및 조직 격리와 최소 권한을 운영 경계에서 강제한다.
|
||||||
|
|
||||||
|
## 포함 경로
|
||||||
|
|
||||||
|
- `internal/platform/` — 설정, Fx 부트스트랩, 로깅, HTTP 서버, 데이터베이스 연결과 마이그레이션을 제공한다.
|
||||||
|
- `apps/server/` — Ariadne 서버 실행 진입점이다.
|
||||||
|
- `apps/migrate/` — 별도 자격 증명을 사용하는 마이그레이션 진입점이다.
|
||||||
|
- `deploy/` — PostgreSQL 역할 등 개발·배포 기반 구성을 제공한다.
|
||||||
|
|
||||||
|
## 제외 경로
|
||||||
|
|
||||||
|
- `internal/domain/` — 오류·조직·수정 작업의 비즈니스 불변 규칙은 domain-model 책임이다.
|
||||||
|
- `internal/integration/` — IOP 실행 포트와 외부 이벤트 검증은 integrations 책임이다.
|
||||||
|
- `apps/client/` — Flutter 사용자 경험과 화면 구성은 client 책임이다.
|
||||||
|
|
||||||
|
## 주요 구성 요소
|
||||||
|
|
||||||
|
- `bootstrap.New` — Fx로 설정, 로깅, 데이터베이스, HTTP 서버 수명주기를 조립한다.
|
||||||
|
- `database.Database` — runtime·identity 연결과 schema/권한 호환 상태를 관리한다.
|
||||||
|
- `database.WithinOrganization` — 트랜잭션 로컬 조직 컨텍스트를 설정하는 유일한 조직 소유 데이터 접근 경계다.
|
||||||
|
- `database.runtimeTableAccess` — 조직 소유 테이블별 runtime 역할의 최소 권한 목록이다.
|
||||||
|
- `database.RunMigrations` — 전용 역할, advisory lock, checksum과 schema 검증을 적용한다.
|
||||||
|
- `httpserver.Server` — `/healthz`, `/readyz`와 보안 헤더를 제공한다.
|
||||||
|
|
||||||
|
## 유지할 패턴
|
||||||
|
|
||||||
|
- 모든 환경 변수는 `ARIADNE_` 접두사를 사용하고 `config.Load`에서 기본값과 양의 duration을 검증한다.
|
||||||
|
- runtime, identity, migration 연결과 역할을 분리하고 서버 시작 시 실제 역할·권한·소유권·RLS를 검증한다.
|
||||||
|
- 조직 소유 데이터 작업은 `WithinOrganization`의 단일 트랜잭션 안에서 수행한다.
|
||||||
|
- 새 조직 소유 테이블은 강제 RLS, 조직 범위 정책, `runtimeTableAccess` 최소 권한을 같은 변경에 포함한다.
|
||||||
|
- 적용된 마이그레이션 파일은 불변으로 두고 새 순번의 상향 마이그레이션을 추가한다.
|
||||||
|
- HTTP 수명주기는 Fx hook과 제한된 timeout을 사용한다.
|
||||||
|
|
||||||
|
## 다른 도메인과의 경계
|
||||||
|
|
||||||
|
- **domain-model**: `organization.ID` 같은 값 타입을 받지만 도메인 판정을 데이터베이스나 HTTP 구현으로 대체하지 않는다.
|
||||||
|
- **integrations**: IOP 구현체와 외부 API를 조립하되 실행 정책의 권한 불변식은 integrations 경계에서도 검증한다.
|
||||||
|
- **client**: 서버는 API와 상태를 제공하고 client의 Flutter 위젯·테마를 직접 소유하지 않는다.
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- 원시 `pgxpool.Pool`을 조직 소유 repository나 다른 패키지에 노출하지 않는다.
|
||||||
|
- 서버 runtime 또는 identity 역할에 슈퍼사용자, `BYPASSRLS`, schema create, 테이블 소유권을 부여하지 않는다.
|
||||||
|
- 감사 이벤트·오류 발생·승인 같은 불변 이력 테이블에 runtime 수정·삭제 권한을 추가하지 않는다.
|
||||||
|
- 운영 환경 쓰기나 최초 전역 사용자·조직 생성 권한을 일반 서버 경계에 임의로 추가하지 않는다.
|
||||||
|
- 이미 적용된 마이그레이션의 내용을 수정하지 않는다.
|
||||||
74
agent-ops/rules/project/rules.md
Normal file
74
agent-ops/rules/project/rules.md
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
# Ariadne 프로젝트 규칙
|
||||||
|
|
||||||
|
## 응답 언어
|
||||||
|
|
||||||
|
- 사용자 응답과 프로젝트 문서는 한국어를 기본으로 작성한다.
|
||||||
|
- 코드 식별자, 환경 변수, 계약 필드명은 기존 영문 표기를 유지한다.
|
||||||
|
|
||||||
|
## 프로젝트 개요
|
||||||
|
|
||||||
|
Ariadne는 여러 조직에서 발생하는 오류를 통합하고, 저장소와 읽기 전용 실행 환경을 분석해 수정·검증·병합 요청까지 이어 주는 플랫폼이다. 오류 이력, 조직과 권한, 연결 대상, 수정 작업 흐름, 승인, 보고, 감사 기록의 기준 시스템은 Ariadne다.
|
||||||
|
|
||||||
|
## 주요 구조
|
||||||
|
|
||||||
|
| 경로 | 역할 |
|
||||||
|
|------|------|
|
||||||
|
| `apps/client/` | Flutter 웹 사용자 화면 |
|
||||||
|
| `apps/server/cmd/ariadne/` | Go 서버 진입점 |
|
||||||
|
| `apps/migrate/cmd/ariadne-migrate/` | 전용 데이터베이스 마이그레이션 명령 |
|
||||||
|
| `internal/domain/` | 오류, 조직, 실패, 수정 작업의 핵심 모델과 규칙 |
|
||||||
|
| `internal/integration/` | IOP 등 외부 실행 계층과의 어댑터 경계 |
|
||||||
|
| `internal/platform/` | 설정, 로깅, 데이터베이스, HTTP 서버, 부트스트랩 |
|
||||||
|
| `contracts/` | 외부 오류 입력과 IOP 실행·실패 JSON 계약 |
|
||||||
|
| `deploy/` | 개발·배포 기반 구성 |
|
||||||
|
|
||||||
|
## 기술 스택
|
||||||
|
|
||||||
|
- 서버: Go 1.24, Uber Fx, Zap
|
||||||
|
- 사용자 화면: Flutter 3.41.5 / Dart 3.11, Material 3
|
||||||
|
- 데이터베이스: PostgreSQL, pgx v5, 강제 행 수준 보안
|
||||||
|
- 계약: 버전이 명시된 JSON Schema
|
||||||
|
- 개발 환경: Docker Compose, Make
|
||||||
|
|
||||||
|
## 프로젝트 특화 컨벤션
|
||||||
|
|
||||||
|
### 조직 및 권한 경계
|
||||||
|
|
||||||
|
- 모든 프로젝트, 저장소, 실행 환경, 오류, 수정 작업, 감사 기록은 조직 범위를 가진다.
|
||||||
|
- 요청 본문의 조직 식별자를 신뢰하지 않는다. 조직 범위는 인증된 주체에서 결정한다.
|
||||||
|
- 오류 입력의 조직과 프로젝트는 인증된 `ingestion_source`에서 함께 결정한다.
|
||||||
|
- 조직 소유 데이터 접근은 `database.WithinOrganization` 안에서 수행하고 원시 연결 풀을 외부에 노출하지 않는다.
|
||||||
|
- 조직 소유 테이블을 추가할 때는 `organization_id`, 조직 범위 외래 키와 색인, 강제 RLS 정책, `database.runtimeTableAccess`의 최소 권한을 함께 추가한다.
|
||||||
|
|
||||||
|
### 데이터베이스 역할
|
||||||
|
|
||||||
|
- 마이그레이션, 서버 실행, 신원 조회 역할을 분리한다.
|
||||||
|
- 실행 역할과 신원 조회 역할에 슈퍼사용자, RLS 우회, 테이블 소유권을 부여하지 않는다.
|
||||||
|
- 신원 조회 경로는 검증된 `issuer + subject`로 활성 조직 멤버십만 조회하며 업무 데이터 권한을 갖지 않는다.
|
||||||
|
- 감사 기록과 승인 기록은 불변 이력으로 취급하고 실행 역할에 수정·삭제 권한을 주지 않는다.
|
||||||
|
|
||||||
|
### 수정 작업과 IOP 경계
|
||||||
|
|
||||||
|
- 운영 환경 연결은 읽기 전용이며 별도 권한·승인 설계 없이 쓰기 기능을 추가하지 않는다.
|
||||||
|
- 분석은 저장소 읽기 전용으로 수행하고 자동 수정은 격리된 작업 가지에서 검증한 뒤 병합 요청을 만든다.
|
||||||
|
- 병합은 항상 사용자 승인 대상이며 IOP에 운영 환경 쓰기나 직접 병합 권한을 전달하지 않는다.
|
||||||
|
- 수정 전 보고 방식은 승인된 수정안 해시와 실행 요청의 `proposal_digest`가 일치해야 한다.
|
||||||
|
- IOP는 LLM과 CLI 실행 계층이다. Ariadne 도메인과 저장 형식을 IOP의 내부 전송·모델 형식에 종속시키지 않는다.
|
||||||
|
- 로컬 형제 저장소를 정식 빌드 의존성으로 사용하지 않는다.
|
||||||
|
|
||||||
|
### 코드와 검증
|
||||||
|
|
||||||
|
- Go 코드는 `apps/`, `internal/` 아래에 두고 외부 연동 계약은 `contracts/`에서 버전별로 관리한다.
|
||||||
|
- 기존 Go 패키지 경계와 Flutter의 `features/`, `shared/` 구성을 우선한다.
|
||||||
|
- 마이그레이션 파일은 순서가 보장되는 이름을 사용하며 적용된 파일의 체크섬을 변경하지 않는다.
|
||||||
|
- 전체 기본 검사는 `make check`다.
|
||||||
|
- PostgreSQL 권한·RLS 통합 검사는 Docker 사용 가능 여부와 전용 역할 환경 변수를 먼저 확인한다.
|
||||||
|
|
||||||
|
## 도메인 매핑
|
||||||
|
|
||||||
|
| 경로 패턴 | 도메인 | rules.md |
|
||||||
|
|----------|--------|----------|
|
||||||
|
| `internal/domain/**` | domain-model | `agent-ops/rules/project/domain/domain-model/rules.md` |
|
||||||
|
| `internal/integration/**`, `contracts/**` | integrations | `agent-ops/rules/project/domain/integrations/rules.md` |
|
||||||
|
| `internal/platform/**`, `apps/server/**`, `apps/migrate/**`, `deploy/**` | platform | `agent-ops/rules/project/domain/platform/rules.md` |
|
||||||
|
| `apps/client/**`, `.fvmrc` | client | `agent-ops/rules/project/domain/client/rules.md` |
|
||||||
|
|
@ -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를 우선한다.
|
||||||
|
- 계약 원문은 복제하지 않고 링크한다.
|
||||||
|
- 코드 진입점과 도메인룰 성격의 상세 경계는 반복하지 않는다.
|
||||||
|
- 불확실한 내용은 `불명확`으로 남긴다.
|
||||||
|
|
@ -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>: <생성/갱신 근거>
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
ui_doc_type: archive-log
|
||||||
|
target: <target>
|
||||||
|
---
|
||||||
|
|
||||||
|
# <target> log
|
||||||
|
|
||||||
|
## <YYYY-MM-DD>
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- <변경 또는 폐기된 정의>
|
||||||
|
|
||||||
|
### Reason
|
||||||
|
|
||||||
|
- <변경 이유>
|
||||||
|
|
||||||
|
### Superseded
|
||||||
|
|
||||||
|
- <대체된 이전 기준 또는 없음>
|
||||||
|
|
@ -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>: <현재 기준으로 남길 결정 요약>
|
||||||
|
|
@ -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는 이 목록에 있어야 한다.
|
||||||
|
|
@ -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>: <초기 결정 또는 변경 요약>
|
||||||
|
|
@ -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와 동일해야 한다.
|
||||||
|
|
@ -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에서도 제거 대상인지 확인한다.
|
||||||
|
|
@ -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/**`는 과거 기록이며 일반 작업에서 읽지 않는다.
|
||||||
|
|
@ -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": []
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
- 없음
|
||||||
|
|
@ -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>: <현재 기준으로 남길 결정 요약>
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
- 없음
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
## 사용자 리뷰 요청
|
||||||
|
|
||||||
|
_기본값은 `없음`이다. 구현 중 새 결정이 필요해 보여도 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 이 섹션은 선택된 Milestone `구현 잠금 > 결정 필요` 항목이 실구현을 차단할 때만 채운다. 외부 환경/secret/서비스 준비, 검증 증거 공백, 반복 실패, 일반 범위 조정은 사용자 리뷰 요청이 아니며 `검증 결과`, `계획 대비 변경 사항`, 또는 code-review의 일반 follow-up plan으로 처리한다._
|
||||||
|
|
||||||
|
- 상태: 없음
|
||||||
|
- 사유 유형: 없음
|
||||||
|
- 연결 대상: 없음
|
||||||
|
- 결정 필요: 없음
|
||||||
|
- 차단 근거: 없음
|
||||||
|
- 실행한 검증/명령: 없음
|
||||||
|
- 자동 후속 불가 이유: 없음
|
||||||
|
- 재개 조건: 없음
|
||||||
|
|
@ -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 상태가 `[스케치]`이면 `구현 잠금` 상태와 관계없이 구현이나 구현 계획을 시작하지 않고 `[계획]` 승격 필요를 보고한다.
|
||||||
|
|
@ -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)로 분리할 항목>
|
||||||
25
agent-ops/skills/common/_templates/roadmap-phase-template.md
Normal file
25
agent-ops/skills/common/_templates/roadmap-phase-template.md
Normal 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에서 유지할 책임 경계 또는 범위 제외 기준>
|
||||||
|
|
@ -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}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
# 전역 마일스톤 실행 순서
|
||||||
|
|
||||||
|
이 문서는 Phase를 가로지르는 Milestone 실행 순서만 기록한다. 위에 있는 항목을 먼저 검토한다.
|
||||||
|
|
||||||
|
## 실행 순서
|
||||||
|
|
||||||
|
<!--
|
||||||
|
작성 규칙:
|
||||||
|
- 실행 후보가 없으면 이 섹션을 비워 둔다.
|
||||||
|
- 항목은 Milestone 제목 링크와 식별용 한 줄 설명만 둔다.
|
||||||
|
- 상태, 목표, 범위, 잠금, 기능, 완료 근거는 각 Milestone 문서를 원본으로 삼는다.
|
||||||
|
- 링크 target은 이 파일 위치 기준 상대 경로로 쓴다.
|
||||||
|
|
||||||
|
예:
|
||||||
|
1. [Milestone 제목](phase/<phase-slug>/milestones/<milestone-slug>.md)
|
||||||
|
이 Milestone에서 다루는 작업을 한 줄로 적는다.
|
||||||
|
-->
|
||||||
85
agent-ops/skills/common/_templates/roadmap-sdd-template.md
Normal file
85
agent-ops/skills/common/_templates/roadmap-sdd-template.md
Normal 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)>
|
||||||
|
|
@ -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 잠금` 상태가 `해제`다.
|
||||||
57
agent-ops/skills/common/_templates/roadmap-template.md
Normal file
57
agent-ops/skills/common/_templates/roadmap-template.md
Normal 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 전체에서 에이전트가 확정할 수 없는 결정 항목이 더 이상 없고 에이전트가 표준선에 따라 실행하면 되는 상태라면 `구현 잠금` 상태를 `해제`로 둔다.
|
||||||
56
agent-ops/skills/common/_templates/skill-template.md
Normal file
56
agent-ops/skills/common/_templates/skill-template.md
Normal 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>
|
||||||
|
- 검증 실패 시: <실패 시 취할 행동 — 롤백, 사용자 알림, 재시도 등>
|
||||||
|
|
||||||
|
## 출력 형식
|
||||||
|
|
||||||
|
```
|
||||||
|
<출력 예시>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- <절대 하면 안 되는 것>
|
||||||
|
- <절대 하면 안 되는 것>
|
||||||
113
agent-ops/skills/common/analyze-roadmap-position/SKILL.md
Normal file
113
agent-ops/skills/common/analyze-roadmap-position/SKILL.md
Normal 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/**`를 읽지 않는다.
|
||||||
94
agent-ops/skills/common/check-roadmap-dependency/SKILL.md
Normal file
94
agent-ops/skills/common/check-roadmap-dependency/SKILL.md
Normal 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`와 설정 오류를 같은 상태로 보고하지 않는다.
|
||||||
327
agent-ops/skills/common/code-review/SKILL.md
Normal file
327
agent-ops/skills/common/code-review/SKILL.md
Normal file
|
|
@ -0,0 +1,327 @@
|
||||||
|
---
|
||||||
|
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 must invoke the plan skill, which reruns finalize-task-routing before writing the next pair, unless the user-review gate requires USER_REVIEW.md.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Code Review
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Review the implementation phase of the plan-code-review loop:
|
||||||
|
|
||||||
|
```text
|
||||||
|
plan skill -> finalize-task-routing -> implementation -> code-review skill
|
||||||
|
^ |
|
||||||
|
+----- WARN/FAIL: invoke plan skill with raw findings -+
|
||||||
|
```
|
||||||
|
|
||||||
|
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, prepare the required next state, archive the active review and plan files, then materialize exactly one next state; for `USER_REVIEW.md` completion, update the stop state, write `complete.log`, and archive the task.
|
||||||
|
- Next state: `PASS` writes `complete.log` and moves the task under `agent-task/archive/YYYY/MM/`; if the task group is `m-<milestone-slug>`, report completion metadata for the runtime event. `WARN` or `FAIL` normally invokes `agent-ops/skills/common/plan/SKILL.md`, which must run `finalize-task-routing` before writing the next active pair; if the user-review gate triggers, write `USER_REVIEW.md` instead. A completed `USER_REVIEW.md` uses the same terminal `complete.log` and archive path as `PASS`.
|
||||||
|
- 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, invoke the plan skill for a normal WARN/FAIL follow-up 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 invoke the plan skill with the current raw findings and let it write the smallest concrete follow-up after fresh routing.
|
||||||
|
- Recovery: if a prior turn appended a verdict without archive or next-state files, do not append another verdict; resume Step 5 preparation/archive from that verdict. If exactly one member of the pair was archived after both archive destinations had been preflighted, verify the archived member and remaining source/destination, finish that archive, then use the post-archive recovery below. If both logs exist with a verdict but the required next state is absent, reconstruct it from those exact logs: PASS resumes `complete.log`; WARN/FAIL reruns the plan skill in `write` mode with raw archived findings and `isolated-reassessment`; a valid user-review gate rerenders `USER_REVIEW.md`. If a prior turn resolved `USER_REVIEW.md` without `complete.log`, resume at the matching finalization step.
|
||||||
|
|
||||||
|
## 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. Invoke the plan skill for a narrower follow-up 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 invoke the plan skill for a normal WARN/FAIL follow-up 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.
|
||||||
|
- This skill reads the active routed names but does not choose follow-up lane/G. Follow-up basenames come only from `plan` executing `finalize-task-routing`.
|
||||||
|
|
||||||
|
Multi-plan runtime contract:
|
||||||
|
|
||||||
|
- Multi-plan work is represented as multiple subtask directories under one shared `{task_group}`. Each subtask directory owns exactly one normal active plan file and one normal active review file.
|
||||||
|
- Multi-plan subtask directory names encode runtime scheduling metadata:
|
||||||
|
- `NN_{subtask_name}` has no runtime dependencies.
|
||||||
|
- `NN+PP[,QQ...]_{subtask_name}` depends on the listed earlier task indices.
|
||||||
|
- Subtask directory names are the runtime dependency source of truth. Preserve them verbatim; do not normalize, reinterpret, infer extra dependencies from numeric order, or choose execution order by agent judgment.
|
||||||
|
- If the user/runtime names a task group, task path, or subtask directory that identifies exactly one active review file, review that directory even when other active review files exist.
|
||||||
|
|
||||||
|
Milestone task group contract:
|
||||||
|
|
||||||
|
- `agent-task/m-<milestone-slug>/` is reserved for Milestone-linked work created by the plan skill.
|
||||||
|
- Do not treat normal task groups that do not start with `m-` as runtime milestone completion targets.
|
||||||
|
- For a selected task path, parse only the first path segment as `{task_group}`. If it matches `^m-[a-z0-9][a-z0-9-]*$`, strip `m-` to get `<milestone-slug>`.
|
||||||
|
- Do not modify `agent-roadmap/**` for milestone routing during code-review finalization. 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.
|
||||||
|
|
||||||
|
Follow-up routing boundary:
|
||||||
|
|
||||||
|
- This skill records current source, actual verification output, and findings, but it must not estimate or recommend the next lane/G.
|
||||||
|
- On WARN/FAIL, invoke the plan skill in `prepare-follow-up` mode with the selected task path and raw current evidence before archiving the current pair.
|
||||||
|
- Do not pass the archived lane, grade, routing score, rationale, or filename as plan-routing input. Archive paths remain evidence pointers, and actual logs/findings remain raw evidence.
|
||||||
|
- The plan skill must complete its full analysis and mandatory `finalize-task-routing` step before it writes the next pair. Code-review must not create a routed follow-up pair directly.
|
||||||
|
- Repair non-behavioral review artifact drift during review instead of failing solely for it when implementation correctness, tests, and contracts remain judgeable.
|
||||||
|
|
||||||
|
Directory states:
|
||||||
|
|
||||||
|
| State | Meaning |
|
||||||
|
|-------|---------|
|
||||||
|
| `PLAN-*-G??.md` + 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` without verdict | Ready for code-review skill |
|
||||||
|
| `PLAN-*-G??.md` + `CODE_REVIEW-*-G??.md` with appended verdict | Review finalization pending; do not append another verdict, resume Step 5 preparation/archive |
|
||||||
|
| Exactly one active pair member + its newly archived counterpart | Partial archive after a preflighted finalization; verify both identities, finish the remaining archive, then resume post-archive recovery |
|
||||||
|
| `complete.log` + `*.log` files | Task complete (PASS or user-review-resolved PASS), before final task-directory archive move |
|
||||||
|
| `USER_REVIEW.md` + `*.log` files | Automatic loop stopped; 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`) | If the newest review log has a verdict and its required next state is absent, post-archive finalization is pending; otherwise the task is terminated mid-loop or abandoned |
|
||||||
|
|
||||||
|
The implementing agent never archives or deletes active files; archiving is this skill's responsibility.
|
||||||
|
|
||||||
|
## Step 1 - Find Active Task
|
||||||
|
|
||||||
|
Find active review files with both globs, excluding `agent-task/archive/**`:
|
||||||
|
|
||||||
|
- `agent-task/*/CODE_REVIEW-*-G??.md`
|
||||||
|
- `agent-task/*/*/CODE_REVIEW-*-G??.md`
|
||||||
|
|
||||||
|
Also note active user-review stops, excluding `agent-task/archive/**`:
|
||||||
|
|
||||||
|
- `agent-task/*/USER_REVIEW.md`
|
||||||
|
- `agent-task/*/*/USER_REVIEW.md`
|
||||||
|
|
||||||
|
Classify the combined set of active `CODE_REVIEW-*-G??.md` and `USER_REVIEW.md` paths. Apply the first matching row:
|
||||||
|
|
||||||
|
| Result | Action |
|
||||||
|
|--------|--------|
|
||||||
|
| Exactly one active path and it is `CODE_REVIEW-*-G??.md` | Review that task; exactly one `PLAN-*-G??.md` is normally expected beside it. If the review already has a verdict and its exact plan counterpart was just archived, use partial-archive recovery instead of reporting a missing plan. |
|
||||||
|
| Exactly one active path and it is `USER_REVIEW.md`, with a 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 | Apply the finalization-recovery scan below; stop only when it finds no recoverable task. |
|
||||||
|
| Multiple active paths | If the user/runtime named a task group, task path, or subtask directory that identifies exactly one active path, use that directory. Otherwise list paths and stop with an ambiguity report; do not choose by agent judgment and do not create a user-review request for routing ambiguity. |
|
||||||
|
|
||||||
|
If a selected task directory contains both `USER_REVIEW.md` and active `PLAN-*-G??.md` or `CODE_REVIEW-*-G??.md`, report an inconsistent loop state instead of overwriting either state.
|
||||||
|
|
||||||
|
Finalization-recovery scan, excluding `agent-task/archive/**`:
|
||||||
|
|
||||||
|
- Candidate A has exactly one active plan, no active review/USER_REVIEW/complete.log, and a newest review log whose verdict belongs to that plan's current loop.
|
||||||
|
- Candidate B has no active plan/review/USER_REVIEW/complete.log, and its newest plan/review logs form one loop whose review verdict requires a missing next state.
|
||||||
|
- Accept only candidates whose exact source/archive identities and verdict can be proven from headers, log suffixes, and review contents. Do not treat a generic log-only abandoned directory as recoverable.
|
||||||
|
- If the user/runtime names one candidate task path, resume it. Otherwise resume only when exactly one candidate exists; list multiple candidates as ambiguity. Use the Core Loop Rules recovery path and never append a second verdict.
|
||||||
|
|
||||||
|
## Step 2 - Load Context
|
||||||
|
|
||||||
|
Count `agent-task/{task_name}/code_review_*.log` in the selected active task directory:
|
||||||
|
|
||||||
|
- `0`: first review. Read the active review file, active plan file, every planned source file, related tests, and files importing/imported by changed files up to 2 levels deep.
|
||||||
|
- `>=1`: follow-up review. Start with `git diff`, `git diff --cached`, and `git log --oneline -5`, then expand to related callers, implementers, tests, and any planned files missing from the diff.
|
||||||
|
|
||||||
|
The diff is the starting point, not the boundary. Follow behavior and API connections far enough to judge correctness.
|
||||||
|
|
||||||
|
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 - Prepare Next State And Archive Active Files
|
||||||
|
|
||||||
|
Do not archive WARN/FAIL files until the next-state content is fully prepared in memory.
|
||||||
|
|
||||||
|
- `PASS`: no routed follow-up preparation is required.
|
||||||
|
- `WARN`/`FAIL`: apply the user-review gate before any rename.
|
||||||
|
- If the gate triggers, render the complete `USER_REVIEW.md` body from `agent-ops/skills/common/code-review/templates/user-review-template.md` in memory.
|
||||||
|
- Otherwise build the follow-up handoff described below and fully execute `agent-ops/skills/common/plan/SKILL.md` in `prepare-follow-up` mode.
|
||||||
|
|
||||||
|
Before preparing a follow-up, count the existing logs and parse each current active basename. Set `current_review_archive_number=count(code_review_*.log)` and `current_plan_archive_number=count(plan_*.log)`. Derive `current_review_archive_name` and `current_plan_archive_name` from the current active files' own lane/grade plus those numbers. These names describe the pair being closed, not the next route.
|
||||||
|
|
||||||
|
The follow-up handoff contains the selected `{task_name}`, current verdict, Required/Suggested/Nit findings, affected files, actual verification output, current ownership/dependency facts, roadmap carryover, `REVIEW_<PARENT_TAG>`, and those predicted current-pair archive names. Keep current active paths only as evidence pointers. Do not add the prior lane, grade, routing score, rationale, or a preferred next route to the neutral routing snapshot, and require plan to omit route-bearing basenames from the isolated routing input. The plan may use current archive names only after routing to render `Archive Evidence Snapshot`.
|
||||||
|
|
||||||
|
- `prepare-follow-up` must return `status: routed`, the exact routed basenames, `prepared_plan`, `prepared_review`, `plan_number`, `current_plan_archive_name`, `current_plan_archive_number`, `current_review_archive_name`, `current_review_archive_number`, `plan_log_number`, `review_log_number`, and `gitignore_repair_needed`. It must have executed `finalize-task-routing` in `isolated-reassessment` mode.
|
||||||
|
- Verify that the returned current archive names/numbers equal the values derived before preparation, and that `plan_log_number` / `review_log_number` are the post-archive counts embedded in the new review stub for its future archive.
|
||||||
|
- If preparation returns `needs_evidence`, continue evidence collection and rerun it before archiving.
|
||||||
|
- If preparation returns `blocked`, leave the verdict-appended active PLAN/CODE_REVIEW pair in place, do not check archive/next-state items, and report a resumable finalization blocker. A later code-review invocation resumes this step without appending another verdict.
|
||||||
|
|
||||||
|
After the required next state is prepared, archive is mandatory for `PASS`, `WARN`, and `FAIL`. Ensure `.gitignore` has the Agent-Ops managed gitignore block for task artifacts before writing `*.log` outputs. Prefer `source agent-ops/bin/ai-ignore.sh && agent_ops_ensure_gitignore_task_artifact_block .gitignore`; if the helper is unavailable, add or update a block containing `!agent-task/`, `!agent-task/**/`, `!agent-task/**/*.md`, `!agent-task/**/*.log`, and `agent-roadmap/current.md`. Apply the repair here when `prepare-follow-up` returned `gitignore_repair_needed: true`.
|
||||||
|
|
||||||
|
Preflight both archive operations before either rename:
|
||||||
|
|
||||||
|
1. Recount existing `code_review_*.log` as `current_review_archive_number`. Parse the active review's lane/grade from its own basename and derive `current_review_archive_name=code_review_{current_review_lane}_{current_review_grade}_{current_review_archive_number}.log`.
|
||||||
|
2. Recount existing `plan_*.log` as `current_plan_archive_number`. Parse the active plan's lane/grade from its own basename and derive `current_plan_archive_name=plan_{current_build_lane}_{current_build_grade}_{current_plan_archive_number}.log`.
|
||||||
|
3. Require both destinations not to exist. When the active stub contains concrete expected archive names, require them to match the derived names; legacy generic placeholders do not override the derived values.
|
||||||
|
4. For WARN/FAIL, require exact matches with both prepared current archive names/numbers. If any check fails, do not rename either file.
|
||||||
|
|
||||||
|
After both operations pass preflight, rename the active review and then the active plan to those exact names. If either current archive count or derived name changed after preparation, discard the prepared pair and rerun plan `prepare-follow-up` before renaming. After archiving, verify that the actual plan/review log counts equal the prepared `plan_log_number` and `review_log_number`; neither active `.md` file remains until Step 6 materializes the prepared next state.
|
||||||
|
|
||||||
|
## Step 6 - Post-Review Actions
|
||||||
|
|
||||||
|
For `PASS`, write `agent-task/{task_name}/complete.log` before reporting. If a `USER_REVIEW.md` stop is resolved as complete/PASS, write the same `complete.log` before archiving that task.
|
||||||
|
|
||||||
|
Complete log template:
|
||||||
|
|
||||||
|
- Template path: `agent-ops/skills/common/code-review/templates/complete-log-template.md`
|
||||||
|
- Copy the template's section order and fill every placeholder from the archived plan/review logs and final verdict.
|
||||||
|
- Do not leave placeholders in `complete.log`.
|
||||||
|
- 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`, materialize the next state prepared in Step 5 immediately after archive:
|
||||||
|
|
||||||
|
- If the user-review gate triggered, write the prepared body to `agent-task/{task_name}/USER_REVIEW.md`. It must use only `milestone-lock`, contain every archived loop entry plus the exact linked decision, and contain no placeholder. Do not write active PLAN/CODE_REVIEW files or `complete.log`.
|
||||||
|
- Otherwise write `prepared_plan` and `prepared_review` byte-for-byte to their routed basenames. Do not rerun, adjust, compare, or upgrade their lane/G after archive.
|
||||||
|
- Verify the written follow-up pair contains the predicted archived plan/review paths in identical `Archive Evidence Snapshot` sections and contains no unresolved token from the review-stub template inventory. Unrelated braces in commands or code are allowed.
|
||||||
|
- A prior local failure never changes the prepared pair into an automatic cloud upgrade.
|
||||||
|
|
||||||
|
If the task group is `m-<milestone-slug>` and the user-review gate triggered, report that the milestone task is blocked on user review; do not emit PASS completion metadata and do not call `update-roadmap`.
|
||||||
|
|
||||||
|
## Step 7 - Complete Review-Only Checklist, Move PASS Task, And Report
|
||||||
|
|
||||||
|
After Step 6:
|
||||||
|
|
||||||
|
- If verdict is `PASS`, determine archive month from the current completion date as `YYYY/MM`, create the needed archive parent directories, then move the selected 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}/{current_review_archive_name}`, where `{final_task_name}` is the archived task path, including `{task_group}/` for split work.
|
||||||
|
- For user-review-resolved PASS, confirm the moved archive contains the resolved `USER_REVIEW.md`, `complete.log`, and the existing archived `plan_*.log` / `code_review_*.log`; do not recreate an active review file only to add a new checklist item.
|
||||||
|
- For `WARN` or `FAIL`, open `agent-task/{task_name}/{current_review_archive_name}`.
|
||||||
|
- Run `git check-ignore -q --` on the generated task artifacts (`plan_*.log`, `code_review_*.log`, `user_review_*.log` when present, `complete.log` when present, and active follow-up `.md` files). If any are ignored, apply the Agent-Ops managed gitignore block and re-check before reporting.
|
||||||
|
- Check every applicable item in `코드리뷰 전용 체크리스트`; leave mutually exclusive verdict items unchecked.
|
||||||
|
- If any applicable item cannot be checked, finish the missing archive, `complete.log`, task-directory move, mandatory plan-skill follow-up, or `USER_REVIEW.md` write first.
|
||||||
|
- Do not recreate an active review file just to update this checklist; update the archived `code_review_*.log`.
|
||||||
|
- Only report after the archived review log has the verdict, applicable checked review-only checklist, required next-state files, for `PASS` or user-review-resolved PASS the final task archive move, for `m-*` PASS tasks the completion event metadata, and for unresolved `USER_REVIEW` the filled `USER_REVIEW.md`.
|
||||||
|
|
||||||
|
Report Required/Suggested counts, archive names, the final task archive path for `PASS`, the new plan path for normal `WARN`/`FAIL`, the `USER_REVIEW.md` path for user review stops, and any `m-*` runtime completion event metadata.
|
||||||
|
|
||||||
|
## Review Dimensions
|
||||||
|
|
||||||
|
| Dimension | Check |
|
||||||
|
|-----------|-------|
|
||||||
|
| Correctness | Logic, edge cases, concurrency, errors |
|
||||||
|
| Completeness | Planned implementation/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
|
||||||
|
|
||||||
|
- `{current_review_archive_name}` exists with the verdict appended and was derived from the archived active review's own route.
|
||||||
|
- `{current_plan_archive_name}` exists and was derived from the archived active plan's own route.
|
||||||
|
- `.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: the plan skill was invoked for the exact task path, completed `finalize-task-routing`, and created new active `PLAN-{build_lane}-GNN.md` and `CODE_REVIEW-{review_lane}-GNN.md` files matching the fresh routed output; no `complete.log`.
|
||||||
|
- WARN/FAIL follow-up: the plan input omitted prior lane/G assessment, and the new active plan/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.
|
||||||
4
agent-ops/skills/common/code-review/agents/openai.yaml
Normal file
4
agent-ops/skills/common/code-review/agents/openai.yaml
Normal 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 task, archive it, and on WARN/FAIL invoke $plan so $finalize-task-routing creates the next routed pair."
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
- 없음
|
||||||
|
|
||||||
|
## 후속 작업
|
||||||
|
|
||||||
|
- 없음
|
||||||
|
|
@ -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`를 작성한다.
|
||||||
162
agent-ops/skills/common/commit-push/SKILL.md
Normal file
162
agent-ops/skills/common/commit-push/SKILL.md
Normal 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` 옵션을 사용하지 않는다
|
||||||
134
agent-ops/skills/common/complete-milestone/SKILL.md
Normal file
134
agent-ops/skills/common/complete-milestone/SKILL.md
Normal 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 후보가 모호한데 자동으로 선택하지 않는다.
|
||||||
180
agent-ops/skills/common/create-agent-ui/SKILL.md
Normal file
180
agent-ops/skills/common/create-agent-ui/SKILL.md
Normal 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`를 추정하지 않는다.
|
||||||
121
agent-ops/skills/common/create-contract/SKILL.md
Normal file
121
agent-ops/skills/common/create-contract/SKILL.md
Normal 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/` 구조가 있어도 사용자 요청 없이 대량 이동하지 않는다.
|
||||||
120
agent-ops/skills/common/create-domain-rule/SKILL.md
Normal file
120
agent-ops/skills/common/create-domain-rule/SKILL.md
Normal 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 파일 생성만 담당한다
|
||||||
93
agent-ops/skills/common/create-handoff/SKILL.md
Normal file
93
agent-ops/skills/common/create-handoff/SKILL.md
Normal 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 변경을 되돌리지 않는다.
|
||||||
156
agent-ops/skills/common/create-readme/SKILL.md
Normal file
156
agent-ops/skills/common/create-readme/SKILL.md
Normal 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에 길게 복사하지 않는다.
|
||||||
234
agent-ops/skills/common/create-roadmap/SKILL.md
Normal file
234
agent-ops/skills/common/create-roadmap/SKILL.md
Normal 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을 `해제` 상태로 만들지 않는다.
|
||||||
|
- 확정되지 않은 제품 방향을 사실처럼 단정하지 않는다.
|
||||||
101
agent-ops/skills/common/create-skill/SKILL.md
Normal file
101
agent-ops/skills/common/create-skill/SKILL.md
Normal 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 에 여러 독립적인 책임을 묶지 않는다
|
||||||
117
agent-ops/skills/common/create-spec/SKILL.md
Normal file
117
agent-ops/skills/common/create-spec/SKILL.md
Normal 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 생성과 무관한 코드 파일을 수정하지 않는다.
|
||||||
138
agent-ops/skills/common/create-test/SKILL.md
Normal file
138
agent-ops/skills/common/create-test/SKILL.md
Normal 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 파일에 기록하지 않는다.
|
||||||
181
agent-ops/skills/common/finalize-task-routing/SKILL.md
Normal file
181
agent-ops/skills/common/finalize-task-routing/SKILL.md
Normal file
|
|
@ -0,0 +1,181 @@
|
||||||
|
---
|
||||||
|
name: finalize-task-routing
|
||||||
|
description: PLAN/CODE_REVIEW 작성 직전 현재 작업 증거만으로 cloud/local lane과 G01-G10 등급을 독립 평가하고 canonical 파일명을 확정한다. 최초 plan, review 실패 후 follow-up plan, 라우팅 재평가, lane/G 판단, routed filename 결정에 사용한다.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Finalize Task Routing
|
||||||
|
|
||||||
|
## 목적
|
||||||
|
|
||||||
|
계획 분석이 끝난 뒤 구현과 리뷰 target의 lane과 G 등급을 처음부터 평가하고 canonical 파일명을 반환한다.
|
||||||
|
이 스킬은 라우팅 판단의 단일 원본이며 plan/review 내용을 작성하거나 task 파일을 직접 생성하지 않는다.
|
||||||
|
|
||||||
|
## 언제 호출할지
|
||||||
|
|
||||||
|
- `plan`이 최초 PLAN/CODE_REVIEW pair를 쓰기 직전
|
||||||
|
- `code-review`의 WARN/FAIL 후 `plan`이 follow-up PLAN/CODE_REVIEW pair를 다시 쓰기 직전
|
||||||
|
- 기존 lane/G 판정이 검증 실패, 증거 충돌, 범위 변화, 소유권 변화로 무효화된 뒤 재평가할 때
|
||||||
|
- 사용자가 현재 작업의 cloud/local, G 등급, canonical task 파일명만 요청할 때
|
||||||
|
|
||||||
|
## 입력
|
||||||
|
|
||||||
|
- `targets`: `build`, `review`, 또는 둘 다. `plan`은 항상 둘 다 전달한다 (필수)
|
||||||
|
- `evaluation_mode`: 이전 라우팅이 없는 최초 평가는 `first-pass`, 무효화된 기존 라우팅이 있는 평가는 `isolated-reassessment` (필수)
|
||||||
|
- `task_snapshot`: 사용자 요구, 현재 scope, 수정/영향 경로, 불변조건, 상태 전이, 검증 계획과 실제 증거 (필수)
|
||||||
|
- `context_snapshot`: 함께 유지해야 하는 source/test/diff/log/contract 범위와 분할 가능성 (필수)
|
||||||
|
- `ownership_snapshot`: 공유 상태, 병행 작업, sibling task, 외부 책임 경계 (필수)
|
||||||
|
- `decision_snapshot`: 미해결 의미 판단, 사용자 권한이 필요한 결정, 외부 환경 의존성 (필수)
|
||||||
|
- `invalidation_evidence`: 검증 실패, 실제 로그, review finding, 변경된 범위 등 현재 판정을 바꾸는 원시 증거 (선택)
|
||||||
|
|
||||||
|
이전 `lane`, `grade`, 점수, 라우팅 사유, routed filename은 입력에서 제외한다.
|
||||||
|
이전 PLAN/CODE_REVIEW 문서의 코드 경로, 실제 로그, finding은 원본에서 재확인한 뒤 원시 증거로만 사용할 수 있다.
|
||||||
|
|
||||||
|
## 먼저 확인할 것
|
||||||
|
|
||||||
|
- [ ] `agent-ops/skills/common/finalize-task-routing/scripts/finalize-task-route.sh`가 실행 가능한가
|
||||||
|
- [ ] 호출자가 plan 분석, scope, split, 검증 계획을 모두 확정했는가
|
||||||
|
- [ ] `targets`마다 필요한 구현 또는 리뷰 작업이 구분되어 있는가
|
||||||
|
- [ ] 이전 lane/G와 그 평가 문구가 입력에서 격리되었는가
|
||||||
|
- [ ] `isolated-reassessment`이면 이전 평가를 보지 않은 새 평가 context/sub-invocation에 중립 snapshot만 전달했는가
|
||||||
|
- [ ] 주장이나 요약이 아니라 현재 파일, diff, 명령 출력, 확정된 제약을 우선 증거로 사용했는가
|
||||||
|
|
||||||
|
## 실행 절차
|
||||||
|
|
||||||
|
1. **평가 상태 초기화**
|
||||||
|
- 호출할 때마다 각 target을 `unrouted`로 시작한다.
|
||||||
|
- `isolated-reassessment`는 이전 평가가 없는 새 context/sub-invocation에서 실행하고, 현재 원시 증거로 재구성한 중립 snapshot만 노출한다.
|
||||||
|
- 호출자가 격리 실행을 제공할 수 없으면 독립 재평가를 완료했다고 주장하지 말고 `status: blocked`, `blocked_reason: isolated-routing-unavailable`을 반환한다.
|
||||||
|
- 이전 lane/G를 승계하거나 하한으로 사용하지 않는다.
|
||||||
|
- 실패 횟수, Required 개수, 이전 G 등급만으로 cloud 또는 상위 G를 선택하지 않는다.
|
||||||
|
- 실패는 자동 승격 조건이 아니라 현재 증거에 추가되는 판정 무효화 사건으로만 취급한다.
|
||||||
|
- 새 결과가 확정되기 전에는 이전 평가와 비교하지 않는다. 필요하면 호출자가 routed 출력 이후에만 감사용 delta를 기록한다.
|
||||||
|
|
||||||
|
2. **폐쇄성 평가**
|
||||||
|
- 각 target을 bounded local execution으로 완료·판정할 수 있는지를 기준으로 아래 값을 `true`, `false`, `unknown` 중 하나로 독립 판정하고 근거를 한 줄로 기록한다.
|
||||||
|
- `scope_closed`: 정확성 조건과 영향 경로가 확정된 범위 안에서 설명되는가
|
||||||
|
- `context_closed`: 중요한 증거를 생략하지 않고 필요한 컨텍스트를 함께 다룰 수 있는가
|
||||||
|
- 계획 분석 결과, 해당 target을 수행하는 동안 긴 컨텍스트를 유지해야 한다고 판단되면 `context_closed=false`로 판정한다.
|
||||||
|
- `verification_closed`: 결정적인 명령과 관찰로 성공 여부를 증명할 수 있는가
|
||||||
|
- `evidence_trusted`: 검증이 의도한 실제 경로를 실행하며 출력이 재현 가능하고 현재 상태와 일치하는가
|
||||||
|
- `ownership_closed`: 공유 상태, 병행 작업, 외부 소유권이 판단을 모호하게 만들지 않는가
|
||||||
|
- `decision_closed`: 사용자 권한이나 미해결 외부 의미 결정 없이 작업을 완료할 수 있는가
|
||||||
|
- 동시성, dirty worktree, 외부 명령, 많은 finding은 그 자체로 lane을 결정하지 않는다. 위 폐쇄성에 미치는 영향만 평가한다.
|
||||||
|
|
||||||
|
3. **판정 가능성 확인**
|
||||||
|
- 하나라도 `unknown`이면 `status: needs_evidence`와 필요한 증거를 반환한다. lane, grade, filename은 반환하지 않는다.
|
||||||
|
- 하나 이상의 값이 `false`이고 cloud의 더 넓은 컨텍스트나 진단도 그 폐쇄 실패를 해소할 수 없으면 `status: blocked`, 폐쇄 실패별 `blocked_reason`, 해제 조건을 반환한다. 사용자 권한, secret, 접근 권한, 제품 결정은 대표적인 예일 뿐이며 이에 한정하지 않는다.
|
||||||
|
- 호출자는 `needs_evidence`를 cloud로 해석하지 말고 증거를 보강한 뒤 이 스킬을 처음부터 다시 실행한다.
|
||||||
|
|
||||||
|
4. **Lane 결정**
|
||||||
|
- 모든 폐쇄성이 `true`인 target만 `local`로 정한다.
|
||||||
|
- `unknown`이 없고 하나 이상의 폐쇄성이 `false`이며 cloud의 더 넓은 컨텍스트나 진단이 그 실패를 실제로 해소할 수 있을 때 `cloud`로 정한다.
|
||||||
|
- `false`를 cloud가 해소할 수 있는지 근거를 기록한다. 해소 가능성을 설명할 수 없으면 추측으로 cloud를 선택하지 않고 Step 3의 `blocked`를 반환한다.
|
||||||
|
- 실패 후에도 현재 폐쇄성이 모두 `true`이면 다시 `local`을 선택할 수 있다.
|
||||||
|
- lane은 capability fit이며 작업량이나 모델 사용량 균형을 위한 값이 아니다.
|
||||||
|
|
||||||
|
5. **G 등급 재산정**
|
||||||
|
- lane을 정한 뒤에만 각 target을 아래 다섯 차원에서 `0`, `1`, `2`로 처음부터 채점한다.
|
||||||
|
- `scope_coupling`: `0` 단일 국소 변경 / `1` 여러 연결 지점 / `2` 다중 모듈·계약
|
||||||
|
- `state_concurrency`: `0` 무상태 / `1` 상태 전이 / `2` 공유 상태·순서·동시성
|
||||||
|
- `blast_irreversibility`: `0` 내부 가역 / `1` 다중 호출자·설정·지속 상태 / `2` 외부 계약·권한·비가역 영향
|
||||||
|
- `evidence_diagnosis`: `0` 직접 증거 / `1` 복수 증거 조합 / `2` 충돌·불신 증거 진단
|
||||||
|
- `verification_complexity`: `0` 단일 결정 명령 / `1` 복수 단계·통합 검증 / `2` 외부·상호작용·장시간 검증
|
||||||
|
- grade는 `max(1, 다섯 점수의 합)`이며 유효 범위는 `G01`부터 `G10`이다.
|
||||||
|
- 이전 grade, 실패 횟수, lane 변경은 점수에 더하지 않는다.
|
||||||
|
|
||||||
|
6. **파일명 확정**
|
||||||
|
- 각 target에 대해 다음 명령을 실행하고 stdout의 grade와 filename을 그대로 사용한다.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
agent-ops/skills/common/finalize-task-routing/scripts/finalize-task-route.sh \
|
||||||
|
<build|review> <local|cloud> \
|
||||||
|
<scope_coupling> <state_concurrency> <blast_irreversibility> \
|
||||||
|
<evidence_diagnosis> <verification_complexity>
|
||||||
|
```
|
||||||
|
|
||||||
|
- 모델이 점수 합산, zero-padding, prefix 조합을 직접 계산하지 않는다.
|
||||||
|
- 두 target은 같은 lane/G를 복사하지 말고 각자의 실행 범위로 독립 평가한다.
|
||||||
|
- 모든 요청 target이 `routed`일 때만 filename을 반환한다.
|
||||||
|
- 결과 확정 뒤 scope, 검증, 증거, 소유권, 결정 조건이 달라지면 결과를 무효화하고 Step 1부터 다시 실행한다.
|
||||||
|
|
||||||
|
## 실행 결과 검증
|
||||||
|
|
||||||
|
- [ ] 모든 요청 target에 여섯 폐쇄성 값과 현재 증거 근거가 있는가
|
||||||
|
- [ ] 재평가가 `isolated-reassessment`로 실행되었고 새 결과 전까지 이전 평가가 노출·비교되지 않았는가
|
||||||
|
- [ ] `unknown` 또는 `blocked` 상태에서 lane/G/filename을 만들지 않았는가
|
||||||
|
- [ ] 이전 lane/G, 실패 횟수, finding 개수를 승계하거나 자동 승격 근거로 사용하지 않았는가
|
||||||
|
- [ ] lane을 먼저 정하고 G 등급을 별도 차원 점수로 산정했는가
|
||||||
|
- [ ] 각 target에 formatter script를 실행했고 grade와 filename을 stdout 그대로 사용했는가
|
||||||
|
- [ ] build/review filename이 target별 formatter 결과와 정확히 일치하는가
|
||||||
|
- 검증 실패 시: 결과를 `unrouted`로 폐기하고 누락된 현재 증거부터 보강한 뒤 전체 평가를 다시 수행한다.
|
||||||
|
|
||||||
|
## 출력 형식
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
status: routed | needs_evidence | blocked
|
||||||
|
evaluation_mode: first-pass | isolated-reassessment
|
||||||
|
targets:
|
||||||
|
build:
|
||||||
|
closures:
|
||||||
|
scope_closed: true
|
||||||
|
context_closed: true
|
||||||
|
verification_closed: true
|
||||||
|
evidence_trusted: true
|
||||||
|
ownership_closed: true
|
||||||
|
decision_closed: true
|
||||||
|
closure_basis:
|
||||||
|
scope_closed: "<current evidence>"
|
||||||
|
context_closed: "<current evidence>"
|
||||||
|
verification_closed: "<current evidence>"
|
||||||
|
evidence_trusted: "<current evidence>"
|
||||||
|
ownership_closed: "<current evidence>"
|
||||||
|
decision_closed: "<current evidence>"
|
||||||
|
lane: local
|
||||||
|
grade_scores:
|
||||||
|
scope_coupling: 1
|
||||||
|
state_concurrency: 1
|
||||||
|
blast_irreversibility: 1
|
||||||
|
evidence_diagnosis: 0
|
||||||
|
verification_complexity: 1
|
||||||
|
grade: G04
|
||||||
|
filename: PLAN-local-G04.md
|
||||||
|
review:
|
||||||
|
closures:
|
||||||
|
scope_closed: true
|
||||||
|
context_closed: false
|
||||||
|
verification_closed: true
|
||||||
|
evidence_trusted: false
|
||||||
|
ownership_closed: true
|
||||||
|
decision_closed: true
|
||||||
|
closure_basis:
|
||||||
|
scope_closed: "<current evidence>"
|
||||||
|
context_closed: "<current evidence>"
|
||||||
|
verification_closed: "<current evidence>"
|
||||||
|
evidence_trusted: "<current evidence>"
|
||||||
|
ownership_closed: "<current evidence>"
|
||||||
|
decision_closed: "<current evidence>"
|
||||||
|
lane: cloud
|
||||||
|
grade_scores:
|
||||||
|
scope_coupling: 1
|
||||||
|
state_concurrency: 1
|
||||||
|
blast_irreversibility: 1
|
||||||
|
evidence_diagnosis: 2
|
||||||
|
verification_complexity: 1
|
||||||
|
grade: G06
|
||||||
|
filename: CODE_REVIEW-cloud-G06.md
|
||||||
|
missing_evidence: []
|
||||||
|
blocked_reason: null
|
||||||
|
```
|
||||||
|
|
||||||
|
`needs_evidence` 또는 `blocked`에서는 해당 target의 `lane`, `grade_scores`, `grade`, `filename`을 `null`로 둔다.
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- 이전 lane/G를 기본값, 최소값, 비교 기준으로 사용하지 않는다.
|
||||||
|
- 기존 평가가 있는 재평가를 같은 평가 context에서 수행하지 않는다.
|
||||||
|
- local 실패를 이유로 cloud로 자동 승격하지 않는다.
|
||||||
|
- 높은 local G로 cloud에 필요한 컨텍스트나 판단을 보상하지 않는다.
|
||||||
|
- 파일 수, 동시성, dirty 상태, Required 개수 같은 단일 휴리스틱으로 lane을 정하지 않는다.
|
||||||
|
- grade나 filename을 formatter script 출력과 다르게 수작업으로 만들지 않는다.
|
||||||
|
- `needs_evidence`를 `cloud`로 치환하거나 미완성 상태에서 routed filename을 만들지 않는다.
|
||||||
|
- PLAN, CODE_REVIEW, archive, complete.log 파일을 직접 생성·수정·이동하지 않는다.
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
interface:
|
||||||
|
display_name: "Finalize Task Routing"
|
||||||
|
short_description: "Finalize task lane, grade, and filenames"
|
||||||
|
default_prompt: "Use $finalize-task-routing after task analysis to independently determine build/review lanes, grades, and canonical filenames."
|
||||||
58
agent-ops/skills/common/finalize-task-routing/scripts/finalize-task-route.sh
Executable file
58
agent-ops/skills/common/finalize-task-routing/scripts/finalize-task-route.sh
Executable file
|
|
@ -0,0 +1,58 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
printf '%s\n' \
|
||||||
|
'usage: finalize-task-route.sh <build|review> <local|cloud> <scope> <state> <blast> <evidence> <verification>' >&2
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ $# -ne 7 ]]; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
target=$1
|
||||||
|
lane=$2
|
||||||
|
shift 2
|
||||||
|
scores=("$@")
|
||||||
|
|
||||||
|
case "$target" in
|
||||||
|
build)
|
||||||
|
prefix=PLAN
|
||||||
|
;;
|
||||||
|
review)
|
||||||
|
prefix=CODE_REVIEW
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$lane" in
|
||||||
|
local|cloud)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
sum=0
|
||||||
|
for score in "${scores[@]}"; do
|
||||||
|
case "$score" in
|
||||||
|
0|1|2)
|
||||||
|
sum=$((sum + score))
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $sum -lt 1 ]]; then
|
||||||
|
sum=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf 'target=%s\n' "$target"
|
||||||
|
printf 'lane=%s\n' "$lane"
|
||||||
|
printf 'grade=G%02d\n' "$sum"
|
||||||
|
printf 'filename=%s-%s-G%02d.md\n' "$prefix" "$lane" "$sum"
|
||||||
280
agent-ops/skills/common/init-agent-ops/SKILL.md
Normal file
280
agent-ops/skills/common/init-agent-ops/SKILL.md
Normal 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와 중복되는 내용을 넣지 않는다.
|
||||||
381
agent-ops/skills/common/plan/SKILL.md
Normal file
381
agent-ops/skills/common/plan/SKILL.md
Normal file
|
|
@ -0,0 +1,381 @@
|
||||||
|
---
|
||||||
|
name: plan
|
||||||
|
description: Analyze the current repository and write a detailed PLAN-{build_lane}-GNN.md plus CODE_REVIEW-{review_lane}-GNN.md stub for implementation work. Use for every feature, refactor, bug fix, and code-review WARN/FAIL follow-up that enters the plan-code-review loop. Every initial or follow-up pair must run finalize-task-routing after analysis and before routed filenames are chosen. Milestone-linked work uses a reserved m-prefixed task group so runtime can route PASS completion events to update-roadmap.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Plan
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Create the planning artifacts for the implementation loop:
|
||||||
|
|
||||||
|
```text
|
||||||
|
plan skill -> analysis -> finalize-task-routing -> 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 task-directory archive move, USER_REVIEW.md, or mandatory plan-skill follow-up
|
||||||
|
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.
|
||||||
|
|
||||||
|
Invocation modes:
|
||||||
|
|
||||||
|
- `write` is the default for initial plans and explicit replans. After routing, this skill archives any prior active pair and writes the new pair.
|
||||||
|
- `prepare-follow-up` is used only when code-review has appended WARN/FAIL but has not archived the active pair. This skill completes analysis, final routing, and exact PLAN/review-stub rendering in memory without mutating repository files. It returns `prepared_plan`, `prepared_review`, their routed basenames, the current pair's predicted archive names/numbers, and the post-archive log counts used by the new pair.
|
||||||
|
- Both modes execute the same mandatory Step 3. `prepare-follow-up` is not a route-only shortcut.
|
||||||
|
|
||||||
|
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.
|
||||||
|
- Lane, grade, and both canonical basenames come only from `agent-ops/skills/common/finalize-task-routing/SKILL.md`.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Final routing boundary:
|
||||||
|
|
||||||
|
- Do not estimate, inherit, or write lane/G while analyzing. Keep the task `unrouted` until all plan scope, split, verification, evidence, ownership, and decision facts are complete.
|
||||||
|
- Execute `agent-ops/skills/common/finalize-task-routing/SKILL.md` for both `build` and `review` after analysis. Its routed outputs are the only source for active PLAN/CODE_REVIEW filenames.
|
||||||
|
- Apply this boundary to first-pass plans, review WARN/FAIL follow-ups, USER_REVIEW replans, and each split subtask independently.
|
||||||
|
- A previous loop's lane, grade, score, rationale, and filename are quarantined. Prior code paths, actual command output, and review findings may be carried only as revalidated raw evidence.
|
||||||
|
- `needs_evidence` requires evidence collection and a fresh full routing run. `blocked` stops plan-file creation. Neither state may produce active routed filenames.
|
||||||
|
- If plan facts change after routing, invalidate both target results and run final routing again before writing files.
|
||||||
|
- Treat non-behavioral review artifact drift and obvious non-behavioral source nits as current-scope evidence; they do not bypass final routing.
|
||||||
|
|
||||||
|
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` without verdict | Ready for code-review skill |
|
||||||
|
| `PLAN-*-G??.md` + `CODE_REVIEW-*-G??.md` with appended verdict | Review finalization is pending. Continue only when code-review invokes `prepare-follow-up`; `write` mode must not overwrite this state. |
|
||||||
|
| `complete.log` + `*.log` files | Task complete (PASS or user-review-resolved PASS), before final task-directory archive move |
|
||||||
|
| `USER_REVIEW.md` + `*.log` files | Automatic loop stopped; 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`) | Inspect the newest review log. A verdict with no required next state is post-archive finalization pending; otherwise the task is terminated mid-loop or abandoned. |
|
||||||
|
|
||||||
|
## Step 1 - Determine Task
|
||||||
|
|
||||||
|
If the user names the task explicitly, use that task group or task path.
|
||||||
|
|
||||||
|
Otherwise, find active plan files with both globs, excluding `agent-task/archive/**`:
|
||||||
|
|
||||||
|
- `agent-task/*/PLAN-*-G??.md`
|
||||||
|
- `agent-task/*/*/PLAN-*-G??.md`
|
||||||
|
|
||||||
|
Also note active user-review stops, excluding `agent-task/archive/**`:
|
||||||
|
|
||||||
|
- `agent-task/*/USER_REVIEW.md`
|
||||||
|
- `agent-task/*/*/USER_REVIEW.md`
|
||||||
|
|
||||||
|
| Result | Action |
|
||||||
|
|--------|--------|
|
||||||
|
| Exactly one | Continue that task |
|
||||||
|
| None | Create a new task only for a feature/refactor/fix/follow-up that belongs in this workflow |
|
||||||
|
| Multiple | If the user/runtime named a task group, task path, or subtask directory that identifies exactly one active plan, use it. Otherwise list paths and stop with an ambiguity report; do not choose by agent judgment and do not create a user-review request for routing ambiguity. |
|
||||||
|
|
||||||
|
The routed plan file is the loop entry point. A missing active plan normally means only that no plan has been started for a new task; do not create task files for casual analysis, status, or review requests unless the user explicitly asks for a plan.
|
||||||
|
|
||||||
|
If no active plan exists but one or more `USER_REVIEW.md` files exist, report 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.
|
||||||
|
|
||||||
|
If the selected review already has an appended verdict, accept it only in `prepare-follow-up` mode invoked by code-review. In every other mode, leave the pair unchanged and report that code-review finalization must resume.
|
||||||
|
|
||||||
|
로드맵 확인:
|
||||||
|
|
||||||
|
- `agent-roadmap/current.md`는 브랜치별 로컬 포인터다. 있으면 구현 계획 파일을 만들기 전에 읽고, 사용자 요청, 브랜치, 변경 경로를 기준으로 관련 Phase와 Milestone을 선택한다.
|
||||||
|
- `agent-roadmap/priority-queue.md`가 있으면 명시 target이 없는 구현 계획에서 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 - Finalize Task Routing
|
||||||
|
|
||||||
|
This step is mandatory and must be the last semantic decision before routed filenames are fixed. Complete Step 2 and prepare the full plan structure in memory before starting it.
|
||||||
|
|
||||||
|
- [ ] **Build neutral input** — prepare current scope, affected paths, invariants, context size, split result, verification plan, actual evidence, ownership, unresolved decisions, and failure evidence for `build` and `review`. Exclude every previous lane, grade, routing score, rationale, filename, and archive basename that exposes them.
|
||||||
|
- [ ] **Select evaluation mode** — use `first-pass` only when no prior routing exists. Review follow-ups, invalidated routes, and USER_REVIEW replans use `isolated-reassessment` and must pass the neutral input to a fresh evaluation context/sub-invocation that has not seen the previous assessment.
|
||||||
|
- [ ] **Run the routing skill** — read and fully execute `agent-ops/skills/common/finalize-task-routing/SKILL.md` with both targets in the selected mode. Do not reproduce or replace its decision logic inside this skill. If isolated evaluation is unavailable, treat the routing result as `blocked`; do not silently evaluate in the current anchored context.
|
||||||
|
- [ ] **Resolve non-final states** — for `needs_evidence`, collect the named evidence and rerun from `unrouted`; for `blocked`, stop without mutating task files and report the exact release condition. In `prepare-follow-up`, leave the verdict-appended active pair in place so code-review recovery can resume without losing the loop state.
|
||||||
|
- [ ] **Accept only routed output** — require independent `build` and `review` closure records, lane, grade scores, GNN, and canonical filename.
|
||||||
|
- [ ] **Freeze the result** — use those exact basenames in Steps 4-6. If any routing input changes before the files are written, discard both outputs and repeat this step from the beginning.
|
||||||
|
|
||||||
|
## Step 4 - Archive Existing Active Files
|
||||||
|
|
||||||
|
In `write` mode, complete this step before writing new active files. In `prepare-follow-up` mode, calculate the same counts and archive names but do not modify any repository file; code-review owns the later archive.
|
||||||
|
|
||||||
|
- Validate that the task directory contains at most one active `PLAN-(local|cloud)-G(0[1-9]|10).md`, at most one active `CODE_REVIEW-(local|cloud)-G(0[1-9]|10).md`, and at most one `USER_REVIEW.md`. Reject ambiguous or malformed active names.
|
||||||
|
- In `write` mode, ensure `.gitignore` has the Agent-Ops managed gitignore block before renaming any active file to `*.log` or creating local `agent-roadmap/current.md`. Prefer `source agent-ops/bin/ai-ignore.sh && agent_ops_ensure_gitignore_task_artifact_block .gitignore`; if the helper is unavailable, add or update a block containing `!agent-task/`, `!agent-task/**/`, `!agent-task/**/*.md`, `!agent-task/**/*.log`, and `agent-roadmap/current.md`. In `prepare-follow-up` mode, only inspect the block and return `gitignore_repair_needed: true|false`; code-review performs any repair after preparation.
|
||||||
|
- Count existing `plan_*.log` as `current_plan_archive_number`. If an active plan exists, parse `current_build_lane` and `current_build_grade` from that active filename and set `current_plan_archive_name=plan_{current_build_lane}_{current_build_grade}_{current_plan_archive_number}.log`. Require that destination not to exist. In `write` mode rename that exact active file to the calculated name; in `prepare-follow-up` only return the name and number. Never use the newly routed build lane/grade to archive the old active plan.
|
||||||
|
- Count existing `code_review_*.log` as `current_review_archive_number`. If an active review exists, parse `current_review_lane` and `current_review_grade` from that active filename and set `current_review_archive_name=code_review_{current_review_lane}_{current_review_grade}_{current_review_archive_number}.log`. Require that destination not to exist. In `write` mode rename that exact active file to the calculated name; in `prepare-follow-up` only return the name and number. Never use the newly routed review lane/grade to archive the old active review.
|
||||||
|
- Count existing `user_review_*.log` as `current_user_review_archive_number`. If `USER_REVIEW.md` exists and the linked Milestone decision is resolved for replanning, set `current_user_review_archive_name=user_review_{current_user_review_archive_number}.log`; require that destination not to exist and rename it only in `write` mode.
|
||||||
|
- Compute `post_archive_plan_log_count`, `post_archive_review_log_count`, and `post_archive_user_review_log_count` from the filesystem after actual archive in `write` mode, or from the predicted addition of each current active file in `prepare-follow-up` mode.
|
||||||
|
|
||||||
|
Set `plan_number=post_archive_plan_log_count`. The new pair's future archive suffixes are `plan_log_number=post_archive_plan_log_count` and `review_log_number=post_archive_review_log_count`. These are intentionally different concepts from `current_plan_archive_number` and `current_review_archive_number`.
|
||||||
|
|
||||||
|
## Step 5 - Write Plan File
|
||||||
|
|
||||||
|
Render the complete plan in memory first. In `write` mode, write it to the routed plan basename. In `prepare-follow-up` mode, return the exact rendered body as `prepared_plan` and do not write it.
|
||||||
|
|
||||||
|
Header line must be exactly:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
<!-- task={task_name} plan={plan_number} 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 the final routed output from 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.
|
||||||
|
- `최종 라우팅`: record the `evaluation_mode` plus `build` and `review` closure results, grade scores, lane, GNN, and canonical filename returned by `finalize-task-routing`. Do not include or compare a previous loop's lane/G.
|
||||||
|
- `구현 체크리스트`: 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
|
||||||
|
|
||||||
|
Read `agent-ops/skills/common/plan/templates/review-stub-template.md` in full only after Step 3 returns `status: routed`.
|
||||||
|
Replace every occurrence of each token below:
|
||||||
|
|
||||||
|
- Scalar tokens: `{date}`, `{task_group}`, `{task_name}`, `{plan_number}`, `{TAG}`, `{build_lane}`, `{build_grade}`, `{review_lane}`, `{review_grade}`, `{plan_log_number}`, `{review_log_number}`.
|
||||||
|
- Plan-copy tokens: `{roadmap_targets_or_omit}`, `{archive_evidence_snapshot_or_omit}`, `{agent_ui_completion_or_omit}`, `{implementation_checklist}`, `{review_checkpoints}`.
|
||||||
|
- Generated row/section tokens: `{implementation_completion_rows}` contains one row for every plan item, and `{verification_result_sections}` contains the fixed verification instructions plus every intermediate/final command from the plan.
|
||||||
|
- `{implementation_user_review_request_section}` is replaced by the full contents of `agent-ops/skills/common/_templates/implementation-user-review-request-section.md`; do not prepend another `사용자 리뷰 요청` heading.
|
||||||
|
|
||||||
|
Use the routed build/review grades independently. Remove optional plan-copy content by replacing its token with an empty string, not by leaving template instructions.
|
||||||
|
In `write` mode, write the rendered stub to the routed review basename. In `prepare-follow-up` mode, return it as `prepared_review` without writing.
|
||||||
|
Do not write or return a prepared pair when either routing target is not `routed`. After rendering, scan for the exact template-token inventory above and reject the output if any known token remains; do not reject unrelated braces in copied commands or code.
|
||||||
|
|
||||||
|
## Naming
|
||||||
|
|
||||||
|
| Tag | Use for |
|
||||||
|
|-----|---------|
|
||||||
|
| `API` | Public API changes |
|
||||||
|
| `REFACTOR` | Internal refactoring |
|
||||||
|
| `TEST` | Test additions/fixes |
|
||||||
|
| `REVIEW_<TAG>` | Follow-up fixes after review |
|
||||||
|
|
||||||
|
## Final Checklist
|
||||||
|
|
||||||
|
- In `write` mode, the routed `PLAN-{build_lane}-GNN.md` and `CODE_REVIEW-{review_lane}-GNN.md` both exist under `agent-task/{task_name}/`. In `prepare-follow-up` mode, neither routed file was written; both exact bodies and basenames were returned while the verdict-appended current pair remained active.
|
||||||
|
- In `write` mode, `.gitignore` has the Agent-Ops managed block that unignores `agent-task/**/*.md` and `agent-task/**/*.log` and ignores local `agent-roadmap/current.md`. In `prepare-follow-up` mode, the block was only inspected and any needed repair was returned as `gitignore_repair_needed`.
|
||||||
|
- Single-plan work stores active files directly under `agent-task/{task_group}/`.
|
||||||
|
- Split work, if any, uses one shared `agent-task/{task_group}/` parent and one subtask directory per plan/review pair with names like `01_core`, `02+01_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={plan_number} tag={TAG} -->`.
|
||||||
|
- The review stub was rendered from `agent-ops/skills/common/plan/templates/review-stub-template.md` after routing and has no unresolved known template token.
|
||||||
|
- In `write` mode, previous active files, if any, were archived with lane/grade parsed from their own basenames and the correct current archive suffixes. In `prepare-follow-up` mode, those archive names were only predicted.
|
||||||
|
- In `write` mode when resuming from `USER_REVIEW.md`, it was archived to the calculated `current_user_review_archive_name` and the resolved 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.
|
||||||
|
- `finalize-task-routing` ran after all analysis for both `build` and `review` in the required evaluation mode; its output status is `routed`, and the active filenames plus `분석 결과 > 최종 라우팅` exactly match its two results.
|
||||||
|
- Review WARN/FAIL follow-ups entered through this plan skill and did not inherit or compare the archived lane/G.
|
||||||
|
- 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.
|
||||||
|
- In `prepare-follow-up`, no repository file was mutated and the returned prepared basenames/bodies, `plan_number`, current archive names/numbers, post-archive log counts, and `gitignore_repair_needed` are complete; in `write`, prior active state was archived with its own parsed route and both new active files were written.
|
||||||
4
agent-ops/skills/common/plan/agents/openai.yaml
Normal file
4
agent-ops/skills/common/plan/agents/openai.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
interface:
|
||||||
|
display_name: "Plan"
|
||||||
|
short_description: "Write implementation plans"
|
||||||
|
default_prompt: "Use $plan to analyze this repository change, run $finalize-task-routing as the final decision, and create the routed PLAN/CODE_REVIEW pair."
|
||||||
106
agent-ops/skills/common/plan/templates/review-stub-template.md
Normal file
106
agent-ops/skills/common/plan/templates/review-stub-template.md
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
<!-- task={task_name} plan={plan_number} 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={date}
|
||||||
|
task={task_name}, plan={plan_number}, tag={TAG}
|
||||||
|
|
||||||
|
{roadmap_targets_or_omit}
|
||||||
|
{archive_evidence_snapshot_or_omit}
|
||||||
|
|
||||||
|
## 이 파일을 읽는 리뷰 에이전트에게
|
||||||
|
|
||||||
|
> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다.
|
||||||
|
|
||||||
|
각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
|
||||||
|
리뷰 완료는 아래 순서까지 끝난 상태를 의미합니다.
|
||||||
|
|
||||||
|
1. 판정을 append한다.
|
||||||
|
2. `CODE_REVIEW-{review_lane}-{review_grade}.md` → `code_review_{review_lane}_{review_grade}_{review_log_number}.log`, `PLAN-{build_lane}-{build_grade}.md` → `plan_{build_lane}_{build_grade}_{plan_log_number}.log`로 아카이브한다.
|
||||||
|
3. PASS이면 `complete.log` 작성 후 active task 디렉터리를 `agent-task/archive/YYYY/MM/{task_name}/`로 이동한다. WARN/FAIL이면 user-review gate를 확인한 뒤 plan skill을 실행해 fresh routing된 다음 active pair를 만들거나 `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` 위치에서 체크한 뒤 보고한다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 구현 항목별 완료 여부
|
||||||
|
|
||||||
|
| 항목 | 완료 여부 |
|
||||||
|
|------|---------|
|
||||||
|
{implementation_completion_rows}
|
||||||
|
|
||||||
|
## 구현 체크리스트
|
||||||
|
|
||||||
|
{implementation_checklist}
|
||||||
|
|
||||||
|
{agent_ui_completion_or_omit}
|
||||||
|
|
||||||
|
## 코드리뷰 전용 체크리스트
|
||||||
|
|
||||||
|
> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다.
|
||||||
|
> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다.
|
||||||
|
|
||||||
|
- [ ] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다.
|
||||||
|
- [ ] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다.
|
||||||
|
- [ ] active `CODE_REVIEW-*-G??.md`를 `code_review_{review_lane}_{review_grade}_{review_log_number}.log`로 아카이브한다.
|
||||||
|
- [ ] active `PLAN-*-G??.md`를 `plan_{build_lane}_{build_grade}_{plan_log_number}.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가 트리거되지 않았으면 plan skill을 실행하고 `finalize-task-routing`의 fresh 결과와 일치하는 다음 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로 이동한다.
|
||||||
|
|
||||||
|
## 계획 대비 변경 사항
|
||||||
|
|
||||||
|
_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._
|
||||||
|
|
||||||
|
## 주요 설계 결정
|
||||||
|
|
||||||
|
_구현 에이전트가 주요 설계 결정 사항을 기록한다._
|
||||||
|
|
||||||
|
{implementation_user_review_request_section}
|
||||||
|
|
||||||
|
## 리뷰어를 위한 체크포인트
|
||||||
|
|
||||||
|
{review_checkpoints}
|
||||||
|
|
||||||
|
## 검증 결과
|
||||||
|
|
||||||
|
{verification_result_sections}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> **[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.
|
||||||
|
|
||||||
|
## 섹션 소유권
|
||||||
|
|
||||||
|
| 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 |
|
||||||
213
agent-ops/skills/common/roadmap-sdd/SKILL.md
Normal file
213
agent-ops/skills/common/roadmap-sdd/SKILL.md
Normal 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의 구현 잠금을 해제하지 않는다.
|
||||||
51
agent-ops/skills/common/router.md
Normal file
51
agent-ops/skills/common/router.md
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
# 공통 스킬 라우터
|
||||||
|
|
||||||
|
라우팅 우선순위:
|
||||||
|
|
||||||
|
- 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` |
|
||||||
|
| 최종 라우팅, task routing, cloud/local 재평가, lane/G 판단, G 등급 재평가, routed filename 결정 | `agent-ops/skills/common/finalize-task-routing/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` |
|
||||||
|
|
||||||
|
라우팅 우선순위:
|
||||||
|
|
||||||
|
- PLAN/CODE_REVIEW 작성 또는 재작성이 요청 범위에 포함되면 `plan`을 선택한다. `plan`이 최종 단계에서 `finalize-task-routing`을 필수 호출한다.
|
||||||
|
- lane/G/canonical filename 판단만 요청되고 plan 문서 작성은 요청되지 않았을 때만 `finalize-task-routing`을 직접 선택한다.
|
||||||
|
- 코드 리뷰 요청은 `code-review`를 선택한다. WARN/FAIL follow-up은 `code-review -> plan -> finalize-task-routing` 순서를 유지한다.
|
||||||
155
agent-ops/skills/common/sync-agent-ui/SKILL.md
Normal file
155
agent-ops/skills/common/sync-agent-ui/SKILL.md
Normal 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의 작업트리 변경을 사용자 결정 없이 되돌리지 않는다.
|
||||||
182
agent-ops/skills/common/sync-milestone-workstate/SKILL.md
Normal file
182
agent-ops/skills/common/sync-milestone-workstate/SKILL.md
Normal 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 이동하지 않는다.
|
||||||
43
agent-ops/skills/common/sync-pull/SKILL.md
Normal file
43
agent-ops/skills/common/sync-pull/SKILL.md
Normal 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 를 거치지 않고 직접 파일을 복사하지 않는다
|
||||||
120
agent-ops/skills/common/sync-push/SKILL.md
Normal file
120
agent-ops/skills/common/sync-push/SKILL.md
Normal 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 를 거치지 않고 직접 파일을 복사하지 않는다
|
||||||
156
agent-ops/skills/common/update-agent-ui/SKILL.md
Normal file
156
agent-ops/skills/common/update-agent-ui/SKILL.md
Normal 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 실패 후 남은 코드 변경을 사용자 결정 없이 되돌리지 않는다.
|
||||||
111
agent-ops/skills/common/update-contract/SKILL.md
Normal file
111
agent-ops/skills/common/update-contract/SKILL.md
Normal 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 계약으로 승격하지 않는다.
|
||||||
|
- 계약 갱신과 무관한 리팩터링을 함께 수행하지 않는다.
|
||||||
117
agent-ops/skills/common/update-domain-rule/SKILL.md
Normal file
117
agent-ops/skills/common/update-domain-rule/SKILL.md
Normal 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 파일 갱신만 담당한다
|
||||||
533
agent-ops/skills/common/update-roadmap/SKILL.md
Normal file
533
agent-ops/skills/common/update-roadmap/SKILL.md
Normal 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의 `구현 잠금`을 직접 해제하지 않는다.
|
||||||
124
agent-ops/skills/common/update-spec/SKILL.md
Normal file
124
agent-ops/skills/common/update-spec/SKILL.md
Normal 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에 길게 쓰지 않는다.
|
||||||
99
agent-ops/skills/common/update-test/SKILL.md
Normal file
99
agent-ops/skills/common/update-test/SKILL.md
Normal 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 파일에 기록하지 않는다.
|
||||||
189
agent-ops/skills/common/validate-agent-ui/SKILL.md
Normal file
189
agent-ops/skills/common/validate-agent-ui/SKILL.md
Normal 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을 자동 생성하지 않는다.
|
||||||
43
agent-roadmap/ROADMAP.md
Normal file
43
agent-roadmap/ROADMAP.md
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
# 로드맵
|
||||||
|
|
||||||
|
## 고정 실행 순서
|
||||||
|
|
||||||
|
- 전역 Milestone 실행 순서는 [전역 마일스톤 실행 순서](priority-queue.md)를 먼저 확인한다.
|
||||||
|
- Phase는 도메인과 책임 영역이며 순차 실행 게이트가 아니다.
|
||||||
|
- 실제 다음 작업 선택은 `priority-queue.md`의 위아래 순서를 우선한다.
|
||||||
|
- 상태, 목표, 범위, 잠금, 기능과 완료 근거는 각 Milestone 문서를 원본으로 삼는다.
|
||||||
|
|
||||||
|
## 전체 목표
|
||||||
|
|
||||||
|
Ariadne를 여러 조직의 오류를 안전하게 수집·통합하고, 연결된 저장소와 읽기 전용 운영 환경을 분석해 실행 가능한 수정 계획, 사용자 알림, 승인 또는 자동 수정, 검증, 병합 요청과 기존 배포 체계 인계까지 추적하는 범용 플랫폼으로 완성한다. IOP는 LLM과 CLI 실행을 담당하고, Ariadne는 조직 권한, 오류 이력, 작업 상태, 승인, 알림, 보고와 감사 기록의 기준 시스템을 유지한다.
|
||||||
|
|
||||||
|
## Phase 흐름
|
||||||
|
|
||||||
|
Phase 흐름은 실행 순서가 아니라 책임 영역별 성숙도를 보여주는 구조적 지도다. 실제 다음 작업 선택은 [전역 마일스톤 실행 순서](priority-queue.md)를 따른다.
|
||||||
|
|
||||||
|
- [진행중] 플랫폼 기반과 조직 경계
|
||||||
|
- 경로: [PHASE.md](phase/platform-foundation/PHASE.md)
|
||||||
|
- 요약: 다중 조직 격리, 신원 경계, 프로젝트와 분석 대상 연결 기반을 확립한다.
|
||||||
|
- [계획] 오류 수집과 분석 대상 결정
|
||||||
|
- 경로: [PHASE.md](phase/error-intelligence/PHASE.md)
|
||||||
|
- 요약: 오류를 멱등하게 수집·묶고 분석할 저장소와 운영 환경을 결정한다.
|
||||||
|
- [계획] 분석과 수정 자동화
|
||||||
|
- 경로: [PHASE.md](phase/remediation-automation/PHASE.md)
|
||||||
|
- 요약: IOP 분석부터 승인, 수정, 검증, 병합 요청과 기존 배포 체계 인계까지 안전한 작업 흐름을 완성한다.
|
||||||
|
- [계획] 운영자 경험
|
||||||
|
- 경로: [PHASE.md](phase/operator-experience/PHASE.md)
|
||||||
|
- 요약: 오류와 수정 작업을 이해하고 검토할 수 있는 사용자 화면과 능동 알림을 제공한다.
|
||||||
|
- [스케치] 서비스 운영과 배포
|
||||||
|
- 경로: [PHASE.md](phase/service-operations/PHASE.md)
|
||||||
|
- 요약: 재시작 복구, 관측성, 보안 배포와 운영 검증 체계를 마련한다.
|
||||||
|
|
||||||
|
## 로딩 정책
|
||||||
|
|
||||||
|
- 일반 작업에서는 이 문서를 매번 읽지 않는다.
|
||||||
|
- Phase를 가로지르는 다음 후보를 고를 때는 [전역 마일스톤 실행 순서](priority-queue.md)를 확인한다.
|
||||||
|
- 기능 추가나 구조 변경 전에는 [current.md](current.md)에서 관련 활성 Phase와 Milestone을 선택해 읽는다.
|
||||||
|
- `current.md`는 브랜치별 로컬 포인터이며 git 추적 대상이 아니다.
|
||||||
|
- `[스케치]` 항목은 구현 계획 대상이 아니며 승격 조건과 사용자 결정을 먼저 해소한다.
|
||||||
|
- 구현 잠금이 남아 있거나 필요한 SDD gate가 통과하지 않은 Milestone은 코드 구현과 구현 계획을 시작하지 않는다.
|
||||||
|
- 완료 후보는 먼저 `[검토중]`으로 두고 완료 근거가 정리된 뒤 archive로 이동한다.
|
||||||
|
- `agent-roadmap/archive/**`는 과거 근거가 필요할 때만 연결된 링크를 따라 읽는다.
|
||||||
26
agent-roadmap/phase/error-intelligence/PHASE.md
Normal file
26
agent-roadmap/phase/error-intelligence/PHASE.md
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Phase: 오류 수집과 분석 대상 결정
|
||||||
|
|
||||||
|
## 상태
|
||||||
|
|
||||||
|
[계획]
|
||||||
|
|
||||||
|
## 목표
|
||||||
|
|
||||||
|
인증된 오류 입력을 잃지 않고 멱등하게 저장하며, 반복 사건을 하나의 오류 묶음으로 통합한다. 등록된 규칙으로 분석할 저장소와 읽기 전용 운영 환경을 결정하고 실행 시점 입력을 고정한다.
|
||||||
|
|
||||||
|
## Milestone 흐름
|
||||||
|
|
||||||
|
이 흐름은 Phase 내부 상태 정리이며, Phase를 가로지르는 실행 순서는 [전역 마일스톤 실행 순서](../../priority-queue.md)를 따른다.
|
||||||
|
|
||||||
|
- [계획] 오류 수집과 중복 통합
|
||||||
|
- 경로: [오류 수집과 중복 통합](milestones/error-ingestion-correlation.md)
|
||||||
|
- 요약: 표준 오류 사건을 입력 출처 범위에서 멱등하게 저장하고 묶는다.
|
||||||
|
- [계획] 분석 대상 결정과 실행 스냅샷
|
||||||
|
- 경로: [분석 대상 결정과 실행 스냅샷](milestones/analysis-target-selection.md)
|
||||||
|
- 요약: 결정적 규칙으로 분석 대상과 기준 리비전을 실행 기록에 고정한다.
|
||||||
|
|
||||||
|
## Phase 경계
|
||||||
|
|
||||||
|
- 오류 본문이 조직이나 프로젝트를 선택하도록 허용하지 않는다.
|
||||||
|
- 중복 통합은 원본 발생 이력을 삭제하거나 덮어쓰지 않는다.
|
||||||
|
- 실제 LLM 분석과 저장소 수정은 분석·수정 자동화 Phase가 소유한다.
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue