sync agent-ops, add documentation files and updates
This commit is contained in:
parent
678302bc3e
commit
41e450744a
54 changed files with 4177 additions and 10 deletions
4
.aiexclude
Normal file
4
.aiexclude
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
# BEGIN Agent-Ops managed ignore
|
||||||
|
agent-task/archive/**
|
||||||
|
agent-ops/roadmap/archive/**
|
||||||
|
# END Agent-Ops managed ignore
|
||||||
8
.claude/settings.json
Normal file
8
.claude/settings.json
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
||||||
|
"permissions": {
|
||||||
|
"deny": [
|
||||||
|
"Read(./agent-task/archive/**)"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
4
.clineignore
Normal file
4
.clineignore
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
# BEGIN Agent-Ops managed ignore
|
||||||
|
agent-task/archive/**
|
||||||
|
agent-ops/roadmap/archive/**
|
||||||
|
# END Agent-Ops managed ignore
|
||||||
30
.clinerules
Normal file
30
.clinerules
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# 공통 규칙
|
||||||
|
|
||||||
|
- **현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
|
||||||
|
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
|
||||||
|
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
|
||||||
|
- 요청 범위를 넘는 변경을 하지 않는다.
|
||||||
|
- 불확실하면 단정하지 말고 후보를 제시한다.
|
||||||
|
- `agent-task/archive/**`는 사용자가 명시적으로 요청한 경우에만 읽는다.
|
||||||
|
- `agent-ops/roadmap/` 디렉터리가 있는 프로젝트에서도 `agent-ops/roadmap/archive/**`는 일반 작업에서 읽지 않는다. 로드맵 과거 완료 내용, 완료 근거, 복원, 비교가 필요한 경우에만 `agent-ops/rules/common/rules-roadmap.md`의 archive 접근 규칙을 따른다.
|
||||||
|
- agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 `agent-ops/rules/common/philosophy.md`를 읽는다.
|
||||||
|
|
||||||
|
**세션 최초 1회 아래 파일을 순서대로 반드시 읽는다.** 파일이나 디렉터리가 없는 항목은 건너뛴다. 그외에 스킵은 금지한다.
|
||||||
|
|
||||||
|
1. `agent-ops/rules/project/rules.md`
|
||||||
|
2. `agent-ops/rules/private/rules.md`
|
||||||
|
3. `agent-ops/roadmap/` 디렉터리가 있으면 `agent-ops/rules/common/rules-roadmap.md`
|
||||||
|
|
||||||
|
# 스킬 규칙
|
||||||
|
|
||||||
|
**아래 경우에 부합되는지 반드시 끝까지 정독해서 읽고, 부합할 경우 `agent-ops/skills/common/router.md`를 작업 최초 1회 읽고 수행한다.** 자동으로 수행하지 않는다. **절대 스킵하지 말고 정독해야한다**
|
||||||
|
- agent-ops 초기화
|
||||||
|
- domain rule 생성
|
||||||
|
- skill 생성
|
||||||
|
- README 생성
|
||||||
|
- 로드맵/마일스톤 생성·갱신
|
||||||
|
- 현재 작업 지점 / 남은 작업 분석
|
||||||
|
- 계획 작성 / plan 생성
|
||||||
|
- 코드 리뷰 / review 진행
|
||||||
|
- git commit / push
|
||||||
|
- agent-ops 업데이트 / 진입 파일 재적용
|
||||||
4
.cursorignore
Normal file
4
.cursorignore
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
# BEGIN Agent-Ops managed ignore
|
||||||
|
agent-task/archive/**
|
||||||
|
agent-ops/roadmap/archive/**
|
||||||
|
# END Agent-Ops managed ignore
|
||||||
30
.cursorrules
Normal file
30
.cursorrules
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# 공통 규칙
|
||||||
|
|
||||||
|
- **현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
|
||||||
|
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
|
||||||
|
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
|
||||||
|
- 요청 범위를 넘는 변경을 하지 않는다.
|
||||||
|
- 불확실하면 단정하지 말고 후보를 제시한다.
|
||||||
|
- `agent-task/archive/**`는 사용자가 명시적으로 요청한 경우에만 읽는다.
|
||||||
|
- `agent-ops/roadmap/` 디렉터리가 있는 프로젝트에서도 `agent-ops/roadmap/archive/**`는 일반 작업에서 읽지 않는다. 로드맵 과거 완료 내용, 완료 근거, 복원, 비교가 필요한 경우에만 `agent-ops/rules/common/rules-roadmap.md`의 archive 접근 규칙을 따른다.
|
||||||
|
- agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 `agent-ops/rules/common/philosophy.md`를 읽는다.
|
||||||
|
|
||||||
|
**세션 최초 1회 아래 파일을 순서대로 반드시 읽는다.** 파일이나 디렉터리가 없는 항목은 건너뛴다. 그외에 스킵은 금지한다.
|
||||||
|
|
||||||
|
1. `agent-ops/rules/project/rules.md`
|
||||||
|
2. `agent-ops/rules/private/rules.md`
|
||||||
|
3. `agent-ops/roadmap/` 디렉터리가 있으면 `agent-ops/rules/common/rules-roadmap.md`
|
||||||
|
|
||||||
|
# 스킬 규칙
|
||||||
|
|
||||||
|
**아래 경우에 부합되는지 반드시 끝까지 정독해서 읽고, 부합할 경우 `agent-ops/skills/common/router.md`를 작업 최초 1회 읽고 수행한다.** 자동으로 수행하지 않는다. **절대 스킵하지 말고 정독해야한다**
|
||||||
|
- agent-ops 초기화
|
||||||
|
- domain rule 생성
|
||||||
|
- skill 생성
|
||||||
|
- README 생성
|
||||||
|
- 로드맵/마일스톤 생성·갱신
|
||||||
|
- 현재 작업 지점 / 남은 작업 분석
|
||||||
|
- 계획 작성 / plan 생성
|
||||||
|
- 코드 리뷰 / review 진행
|
||||||
|
- git commit / push
|
||||||
|
- agent-ops 업데이트 / 진입 파일 재적용
|
||||||
4
.geminiignore
Normal file
4
.geminiignore
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
# BEGIN Agent-Ops managed ignore
|
||||||
|
agent-task/archive/**
|
||||||
|
agent-ops/roadmap/archive/**
|
||||||
|
# END Agent-Ops managed ignore
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -31,3 +31,6 @@ migrate_working_dir/
|
||||||
.flutter-plugins-dependencies
|
.flutter-plugins-dependencies
|
||||||
/build/
|
/build/
|
||||||
/coverage/
|
/coverage/
|
||||||
|
|
||||||
|
# Agent-Ops Private Rules
|
||||||
|
agent-ops/rules/private/
|
||||||
|
|
|
||||||
30
AGENTS.md
Normal file
30
AGENTS.md
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# 공통 규칙
|
||||||
|
|
||||||
|
- **현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
|
||||||
|
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
|
||||||
|
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
|
||||||
|
- 요청 범위를 넘는 변경을 하지 않는다.
|
||||||
|
- 불확실하면 단정하지 말고 후보를 제시한다.
|
||||||
|
- `agent-task/archive/**`는 사용자가 명시적으로 요청한 경우에만 읽는다.
|
||||||
|
- `agent-ops/roadmap/` 디렉터리가 있는 프로젝트에서도 `agent-ops/roadmap/archive/**`는 일반 작업에서 읽지 않는다. 로드맵 과거 완료 내용, 완료 근거, 복원, 비교가 필요한 경우에만 `agent-ops/rules/common/rules-roadmap.md`의 archive 접근 규칙을 따른다.
|
||||||
|
- agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 `agent-ops/rules/common/philosophy.md`를 읽는다.
|
||||||
|
|
||||||
|
**세션 최초 1회 아래 파일을 순서대로 반드시 읽는다.** 파일이나 디렉터리가 없는 항목은 건너뛴다. 그외에 스킵은 금지한다.
|
||||||
|
|
||||||
|
1. `agent-ops/rules/project/rules.md`
|
||||||
|
2. `agent-ops/rules/private/rules.md`
|
||||||
|
3. `agent-ops/roadmap/` 디렉터리가 있으면 `agent-ops/rules/common/rules-roadmap.md`
|
||||||
|
|
||||||
|
# 스킬 규칙
|
||||||
|
|
||||||
|
**아래 경우에 부합되는지 반드시 끝까지 정독해서 읽고, 부합할 경우 `agent-ops/skills/common/router.md`를 작업 최초 1회 읽고 수행한다.** 자동으로 수행하지 않는다. **절대 스킵하지 말고 정독해야한다**
|
||||||
|
- agent-ops 초기화
|
||||||
|
- domain rule 생성
|
||||||
|
- skill 생성
|
||||||
|
- README 생성
|
||||||
|
- 로드맵/마일스톤 생성·갱신
|
||||||
|
- 현재 작업 지점 / 남은 작업 분석
|
||||||
|
- 계획 작성 / plan 생성
|
||||||
|
- 코드 리뷰 / review 진행
|
||||||
|
- git commit / push
|
||||||
|
- agent-ops 업데이트 / 진입 파일 재적용
|
||||||
30
CLAUDE.md
Normal file
30
CLAUDE.md
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# 공통 규칙
|
||||||
|
|
||||||
|
- **현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
|
||||||
|
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
|
||||||
|
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
|
||||||
|
- 요청 범위를 넘는 변경을 하지 않는다.
|
||||||
|
- 불확실하면 단정하지 말고 후보를 제시한다.
|
||||||
|
- `agent-task/archive/**`는 사용자가 명시적으로 요청한 경우에만 읽는다.
|
||||||
|
- `agent-ops/roadmap/` 디렉터리가 있는 프로젝트에서도 `agent-ops/roadmap/archive/**`는 일반 작업에서 읽지 않는다. 로드맵 과거 완료 내용, 완료 근거, 복원, 비교가 필요한 경우에만 `agent-ops/rules/common/rules-roadmap.md`의 archive 접근 규칙을 따른다.
|
||||||
|
- agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 `agent-ops/rules/common/philosophy.md`를 읽는다.
|
||||||
|
|
||||||
|
**세션 최초 1회 아래 파일을 순서대로 반드시 읽는다.** 파일이나 디렉터리가 없는 항목은 건너뛴다. 그외에 스킵은 금지한다.
|
||||||
|
|
||||||
|
1. `agent-ops/rules/project/rules.md`
|
||||||
|
2. `agent-ops/rules/private/rules.md`
|
||||||
|
3. `agent-ops/roadmap/` 디렉터리가 있으면 `agent-ops/rules/common/rules-roadmap.md`
|
||||||
|
|
||||||
|
# 스킬 규칙
|
||||||
|
|
||||||
|
**아래 경우에 부합되는지 반드시 끝까지 정독해서 읽고, 부합할 경우 `agent-ops/skills/common/router.md`를 작업 최초 1회 읽고 수행한다.** 자동으로 수행하지 않는다. **절대 스킵하지 말고 정독해야한다**
|
||||||
|
- agent-ops 초기화
|
||||||
|
- domain rule 생성
|
||||||
|
- skill 생성
|
||||||
|
- README 생성
|
||||||
|
- 로드맵/마일스톤 생성·갱신
|
||||||
|
- 현재 작업 지점 / 남은 작업 분석
|
||||||
|
- 계획 작성 / plan 생성
|
||||||
|
- 코드 리뷰 / review 진행
|
||||||
|
- git commit / push
|
||||||
|
- agent-ops 업데이트 / 진입 파일 재적용
|
||||||
30
GEMINI.md
Normal file
30
GEMINI.md
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# 공통 규칙
|
||||||
|
|
||||||
|
- **현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
|
||||||
|
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
|
||||||
|
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
|
||||||
|
- 요청 범위를 넘는 변경을 하지 않는다.
|
||||||
|
- 불확실하면 단정하지 말고 후보를 제시한다.
|
||||||
|
- `agent-task/archive/**`는 사용자가 명시적으로 요청한 경우에만 읽는다.
|
||||||
|
- `agent-ops/roadmap/` 디렉터리가 있는 프로젝트에서도 `agent-ops/roadmap/archive/**`는 일반 작업에서 읽지 않는다. 로드맵 과거 완료 내용, 완료 근거, 복원, 비교가 필요한 경우에만 `agent-ops/rules/common/rules-roadmap.md`의 archive 접근 규칙을 따른다.
|
||||||
|
- agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 `agent-ops/rules/common/philosophy.md`를 읽는다.
|
||||||
|
|
||||||
|
**세션 최초 1회 아래 파일을 순서대로 반드시 읽는다.** 파일이나 디렉터리가 없는 항목은 건너뛴다. 그외에 스킵은 금지한다.
|
||||||
|
|
||||||
|
1. `agent-ops/rules/project/rules.md`
|
||||||
|
2. `agent-ops/rules/private/rules.md`
|
||||||
|
3. `agent-ops/roadmap/` 디렉터리가 있으면 `agent-ops/rules/common/rules-roadmap.md`
|
||||||
|
|
||||||
|
# 스킬 규칙
|
||||||
|
|
||||||
|
**아래 경우에 부합되는지 반드시 끝까지 정독해서 읽고, 부합할 경우 `agent-ops/skills/common/router.md`를 작업 최초 1회 읽고 수행한다.** 자동으로 수행하지 않는다. **절대 스킵하지 말고 정독해야한다**
|
||||||
|
- agent-ops 초기화
|
||||||
|
- domain rule 생성
|
||||||
|
- skill 생성
|
||||||
|
- README 생성
|
||||||
|
- 로드맵/마일스톤 생성·갱신
|
||||||
|
- 현재 작업 지점 / 남은 작업 분석
|
||||||
|
- 계획 작성 / plan 생성
|
||||||
|
- 코드 리뷰 / review 진행
|
||||||
|
- git commit / push
|
||||||
|
- agent-ops 업데이트 / 진입 파일 재적용
|
||||||
37
README.md
37
README.md
|
|
@ -121,6 +121,43 @@ Ensure that the host app does not redeclare duplicate FCM services unless explic
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Test Harness Strategy
|
||||||
|
|
||||||
|
This repository keeps the plugin and its independent consumer test app together:
|
||||||
|
|
||||||
|
```text
|
||||||
|
mattermost-push-plugin/
|
||||||
|
lib/ # Public Dart API and Flutter-facing behavior
|
||||||
|
android/ # Android native plugin implementation
|
||||||
|
test/ # Dart unit tests for the plugin contract
|
||||||
|
example/ # Thin Flutter app used as the integration test harness
|
||||||
|
test/ # Widget tests for the harness app
|
||||||
|
integration_test/ # Device/emulator integration tests
|
||||||
|
```
|
||||||
|
|
||||||
|
The `example/` app is the official place to validate plugin integration without coupling this package to any consuming product app. Consumer apps should only test their own wiring, such as calling initialization, storing credentials, and connecting navigation callbacks.
|
||||||
|
|
||||||
|
Recommended verification layers:
|
||||||
|
|
||||||
|
1. `flutter test` from the repository root for Dart API behavior, event parsing, callback routing, and token formatting.
|
||||||
|
2. `flutter test` from `example/` for the test harness app.
|
||||||
|
3. Android unit tests from `example/android` for native payload, storage, signing, and ACK behavior.
|
||||||
|
4. `flutter test integration_test` from `example/` on a device or emulator for plugin registration, method/event channels, notification-open routing, and manifest integration.
|
||||||
|
5. Manual smoke tests for true Firebase FCM delivery and real Mattermost server ACK flows, because those depend on external infrastructure.
|
||||||
|
|
||||||
|
Recommended local commands:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
flutter analyze
|
||||||
|
flutter test
|
||||||
|
(cd example && flutter analyze && flutter test)
|
||||||
|
(cd example/android && ./gradlew testDebugUnitTest)
|
||||||
|
```
|
||||||
|
|
||||||
|
Android Gradle tests require a configured Android SDK via `ANDROID_HOME` or `example/android/local.properties`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Verification & Manual Smoke Testing Checklist
|
## Verification & Manual Smoke Testing Checklist
|
||||||
|
|
||||||
Since full end-to-end FCM flows cannot be automated in headless test runners, verify functionality manually using the following checklist:
|
Since full end-to-end FCM flows cannot be automated in headless test runners, verify functionality manually using the following checklist:
|
||||||
|
|
|
||||||
1
agent-ops/.version
Normal file
1
agent-ops/.version
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
1.1.52
|
||||||
252
agent-ops/bin/ai-ignore.sh
Executable file
252
agent-ops/bin/ai-ignore.sh
Executable file
|
|
@ -0,0 +1,252 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Shared AI ignore / permission defaults for init and sync flows.
|
||||||
|
AGENT_OPS_TASK_ARCHIVE_IGNORE_PATTERN="agent-task/archive/**"
|
||||||
|
AGENT_OPS_ROADMAP_ARCHIVE_IGNORE_PATTERN="agent-ops/roadmap/archive/**"
|
||||||
|
AGENT_OPS_AI_IGNORE_BLOCK_BEGIN="# BEGIN Agent-Ops managed ignore"
|
||||||
|
AGENT_OPS_AI_IGNORE_BLOCK_END="# END Agent-Ops managed ignore"
|
||||||
|
AGENT_OPS_AI_IGNORE_FILES=(".geminiignore" ".aiexclude" ".cursorignore" ".clineignore")
|
||||||
|
AGENT_OPS_AI_PERMISSION_FILES=(".claude/settings.json" "opencode.json")
|
||||||
|
AGENT_OPS_AI_SYNC_FILES=("${AGENT_OPS_AI_IGNORE_FILES[@]}" "${AGENT_OPS_AI_PERMISSION_FILES[@]}")
|
||||||
|
|
||||||
|
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_OPS_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_OPS_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 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;
|
||||||
|
|
||||||
|
.permissions = ((.permissions // {}) | as_object)
|
||||||
|
| .permissions.deny = (
|
||||||
|
(.permissions.deny | as_array)
|
||||||
|
| append_unique("Read(./agent-task/archive/**)")
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
agent_ops_merge_json_with_jq \
|
||||||
|
"$file" \
|
||||||
|
"$filter" \
|
||||||
|
"Note: .claude/settings.json exists; add Read(./agent-task/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)
|
||||||
|
| index("Read(./agent-task/archive/**)")
|
||||||
|
'
|
||||||
|
|
||||||
|
if command -v jq >/dev/null 2>&1; then
|
||||||
|
jq -e "$filter" "$file" >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
grep -q "agent-task/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)
|
||||||
|
| .permission.read["agent-task/archive/**"] = "deny"
|
||||||
|
| .permission.glob = ((.permission.glob // {}) | as_object)
|
||||||
|
| .permission.glob["agent-task/archive/**"] = "deny"
|
||||||
|
| .watcher = ((.watcher // {}) | as_object)
|
||||||
|
| .watcher.ignore = (
|
||||||
|
(.watcher.ignore | as_array)
|
||||||
|
| append_unique("agent-task/archive/**")
|
||||||
|
| append_unique("agent-ops/roadmap/archive/**")
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
agent_ops_merge_json_with_jq \
|
||||||
|
"$file" \
|
||||||
|
"$filter" \
|
||||||
|
"Note: opencode.json exists; add agent-task/archive/** read/glob deny and agent-task/archive/** plus agent-ops/roadmap/archive/** 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 ((.watcher.ignore | as_array) | index("agent-task/archive/**") and index("agent-ops/roadmap/archive/**"))
|
||||||
|
'
|
||||||
|
|
||||||
|
if command -v jq >/dev/null 2>&1; then
|
||||||
|
jq -e "$filter" "$file" >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
grep -q "agent-task/archive" "$file" && grep -q "agent-ops/roadmap/archive" "$file"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
agent_ops_warn_existing_roadmap_hard_deny() {
|
||||||
|
local target_dir="$1"
|
||||||
|
local found="0"
|
||||||
|
local file
|
||||||
|
|
||||||
|
file="$target_dir/.claude/settings.json"
|
||||||
|
if [[ -f "$file" ]]; then
|
||||||
|
if command -v jq >/dev/null 2>&1; then
|
||||||
|
if jq -e '
|
||||||
|
def as_array:
|
||||||
|
if type == "array" then . elif . == null then [] else [.] end;
|
||||||
|
(.permissions.deny | as_array)
|
||||||
|
| index("Read(./agent-ops/roadmap/archive/**)")
|
||||||
|
' "$file" >/dev/null 2>&1; then
|
||||||
|
found="1"
|
||||||
|
fi
|
||||||
|
elif grep -q "Read(./agent-ops/roadmap/archive/**)" "$file"; then
|
||||||
|
found="1"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
file="$target_dir/opencode.json"
|
||||||
|
if [[ -f "$file" ]]; then
|
||||||
|
if command -v jq >/dev/null 2>&1; then
|
||||||
|
if jq -e '
|
||||||
|
(.permission.read["agent-ops/roadmap/archive/**"] == "deny")
|
||||||
|
or (.permission.glob["agent-ops/roadmap/archive/**"] == "deny")
|
||||||
|
' "$file" >/dev/null 2>&1; then
|
||||||
|
found="1"
|
||||||
|
fi
|
||||||
|
elif grep -Eq '"agent-ops/roadmap/archive/\*\*"[[:space:]]*:[[:space:]]*"deny"' "$file"; then
|
||||||
|
found="1"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$found" == "1" ]]; then
|
||||||
|
echo " Warning: 기존 roadmap archive hard deny는 사용자 설정으로 보고 보존했습니다. 링크 기반 archive 읽기가 필요하면 수동 확인하세요."
|
||||||
|
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
|
||||||
|
|
||||||
|
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": [
|
||||||
|
"Read(./agent-task/archive/**)"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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",
|
||||||
|
"permission": {
|
||||||
|
"read": {
|
||||||
|
"agent-task/archive/**": "deny"
|
||||||
|
},
|
||||||
|
"glob": {
|
||||||
|
"agent-task/archive/**": "deny"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"watcher": {
|
||||||
|
"ignore": [
|
||||||
|
"agent-task/archive/**",
|
||||||
|
"agent-ops/roadmap/archive/**"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
elif ! agent_ops_opencode_config_complete "$target_dir/opencode.json"; then
|
||||||
|
agent_ops_merge_opencode_config "$target_dir/opencode.json"
|
||||||
|
fi
|
||||||
|
|
||||||
|
agent_ops_warn_existing_roadmap_hard_deny "$target_dir"
|
||||||
|
}
|
||||||
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
|
||||||
|
}
|
||||||
86
agent-ops/bin/init-agent-ops.sh
Executable file
86
agent-ops/bin/init-agent-ops.sh
Executable file
|
|
@ -0,0 +1,86 @@
|
||||||
|
#!/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"
|
||||||
|
}
|
||||||
|
|
||||||
|
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"
|
||||||
|
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
|
||||||
|
|
||||||
|
echo "Successfully initialized agent-ops in $TARGET_DIR"
|
||||||
|
echo "Note: agent-ops/rules/project and agent-ops/skills/project are initialized as empty."
|
||||||
331
agent-ops/bin/sync.sh
Executable file
331
agent-ops/bin/sync.sh
Executable file
|
|
@ -0,0 +1,331 @@
|
||||||
|
#!/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
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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(agentic-framework) → 현재 프로젝트 로 pull"
|
||||||
|
echo ""
|
||||||
|
echo " target: 폴더명 (동일 레벨 탐색) | 상대경로 | 절대경로"
|
||||||
|
echo " agentic-framework에서 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 모드: agentic-framework → 현재 프로젝트 ─────────────────────────────
|
||||||
|
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: agentic-framework에서는 --pull을 사용할 수 없습니다.${RESET}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ ! -f "$TARGET/.agent-ops-source" ]]; then
|
||||||
|
echo -e "${RED}Error: target이 agentic-framework가 아닙니다 (.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 | framework 버전: $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
|
||||||
|
|
||||||
|
# ── agentic-framework에서 다른 프로젝트로 ────────────────────────────────────
|
||||||
|
if [[ "$IS_FRAMEWORK" == "1" ]]; then
|
||||||
|
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
|
||||||
|
|
||||||
|
# ── 일반 프로젝트에서 agentic-framework로 (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이 agentic-framework가 아닙니다 (.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 | framework 버전: $DST_VER"
|
||||||
|
|
||||||
|
COMMON_CHANGED="1"
|
||||||
|
if ! common_differs "$SRC_AO" "$DST_AO"; then
|
||||||
|
COMMON_CHANGED="0"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$COMMON_CHANGED" == "1" ]] && version_gt "$DST_VER" "$SRC_VER"; then
|
||||||
|
echo -e "${RED}⚠ 버전 충돌: framework($DST_VER) > current($SRC_VER)${RESET}"
|
||||||
|
echo -e "${YELLOW} 먼저 sync-pull로 내려받은 뒤 재시도하세요.${RESET}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$COMMON_CHANGED" == "0" ]]; then
|
||||||
|
echo " 공통 파일 변경 없음: .version 차이는 무시하고 버전 갱신/커밋을 건너뜀"
|
||||||
|
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"
|
||||||
|
|
||||||
|
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>**: <어디까지가 이 도메인이고 어디서부터 저 도메인인지>
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- <이 도메인 코드에서 하면 안 되는 것>
|
||||||
86
agent-ops/rules/common/philosophy.md
Normal file
86
agent-ops/rules/common/philosophy.md
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
# 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 반영 여부와 호출 타이밍은 런타임이 완료 이벤트를 보고 판단한다.
|
||||||
|
|
||||||
|
## 로드맵
|
||||||
|
|
||||||
|
- 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이 파일명만 봐도 될 일을 본문까지 읽어 판단하고 있다.
|
||||||
107
agent-ops/rules/common/rules-roadmap.md
Normal file
107
agent-ops/rules/common/rules-roadmap.md
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
# 로드맵 규칙
|
||||||
|
|
||||||
|
`agent-ops/roadmap/` 디렉터리가 있는 프로젝트에서만 적용한다.
|
||||||
|
|
||||||
|
## 구조
|
||||||
|
|
||||||
|
- 최상위 로드맵은 `agent-ops/roadmap/ROADMAP.md`다.
|
||||||
|
- 활성 Phase는 `agent-ops/roadmap/phase/<phase-slug>/PHASE.md`에 둔다.
|
||||||
|
- 활성 Milestone은 해당 Phase 아래 `agent-ops/roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md`에 둔다.
|
||||||
|
- `<phase-slug>`와 `<milestone-slug>`는 소문자 영문, 숫자, 하이픈만 사용한다.
|
||||||
|
- 완료된 Phase는 scaffold 그대로 `agent-ops/roadmap/archive/phase/<phase-slug>/PHASE.md`로 이동하고, 하위 Milestone도 `archive/phase/<phase-slug>/milestones/` 아래에 둔다.
|
||||||
|
- 진행중 Phase 안에서 완료된 Milestone은 활성 `PHASE.md`에 짧은 archive 링크를 남기고, 상세 문서는 `agent-ops/roadmap/archive/phase/<phase-slug>/milestones/`로 이동한다.
|
||||||
|
- archive `PHASE.md`는 Phase 자체가 완료/폐기될 때만 만들며, 진행중 Phase의 완료 Milestone만 archive된 경우 archive Phase 디렉터리에 `milestones/`만 있을 수 있다.
|
||||||
|
|
||||||
|
## 로딩
|
||||||
|
|
||||||
|
- 세션 최초 1회 `agent-ops/roadmap/current.md`를 읽고 활성 Phase, 활성 Milestone의 이름, 경로, 선택 규칙만 짧게 기억한다.
|
||||||
|
- 일반 작업에서는 `ROADMAP.md`를 읽지 않는다.
|
||||||
|
- 일반 작업에서는 `agent-ops/roadmap/archive/**`를 읽지 않는다.
|
||||||
|
- 기능 추가, 구조 변경, 구현 계획, 현재 작업 분석 전에는 요청과 변경 파일에 맞는 활성 Phase와 활성 Milestone 문서를 읽는다.
|
||||||
|
- `ROADMAP.md`는 로드맵 생성/갱신, Phase 추가/삭제/전환, 전체 구조 변경, 활성 범위 밖 작업 확인 때만 읽는다.
|
||||||
|
- 과거 완료 내용, 완료 근거, 복원, 비교가 필요한 경우에만 `ROADMAP.md` 또는 `PHASE.md`에 있는 archive 링크를 따라가서 필요한 archive 문서만 읽는다.
|
||||||
|
|
||||||
|
## Phase와 Milestone 선택
|
||||||
|
|
||||||
|
- `current.md`는 현재 작업 위치가 아니라 활성 Phase와 활성 Milestone 후보 목록이다.
|
||||||
|
- 활성 Phase는 `agent-ops/roadmap/phase/**/PHASE.md`만 대상으로 한다.
|
||||||
|
- 활성 Milestone은 `agent-ops/roadmap/phase/**/milestones/*.md`만 대상으로 한다.
|
||||||
|
- `current.md`에는 `[완료]` 또는 `[폐기]` Phase/Milestone을 남기지 않는다. 완료 후보는 승인 전까지 `[검토중]`으로 둔다.
|
||||||
|
- "로드맵에 추가", "마일스톤에 추가"처럼 target 없는 신규 작업 추가 요청은 `update-roadmap` 스킬로 처리하고, 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의 목표 또는 범위 제외와 요청이 충돌하면 구현 전에 사용자에게 확인한다.
|
||||||
|
|
||||||
|
## 상태 표기
|
||||||
|
|
||||||
|
- Phase와 Milestone 상태 표기는 `[계획]`, `[진행중]`, `[검토중]`, `[완료]`, `[보류]`, `[폐기]` 중 하나만 사용한다.
|
||||||
|
- 갱신 범위에 포함된 기존 진행 상태 표기는 `[진행중]`으로 정리한다.
|
||||||
|
- `[검토중]`은 모든 필수 작업과 완료 기준이 충족된 것으로 보이나, 사용자의 최종 완료 확인과 archive 승인이 아직 남은 완료 후보 상태다.
|
||||||
|
- `[검토중]` 항목은 활성 경로에 남기고 `current.md`의 활성 후보로 유지할 수 있다.
|
||||||
|
- 검토 결과 보완이 필요하면 별도 reopen 상태를 만들지 않고 `[진행중]`으로 되돌린 뒤 `완료 리뷰` 또는 `작업 컨텍스트`에 보완 방향을 남긴다.
|
||||||
|
- 검토 결과 보류 또는 폐기 결정이 나면 `[보류]` 또는 `[폐기]`로 전환한다.
|
||||||
|
- `ROADMAP.md`의 Phase 흐름과 `PHASE.md`의 Milestone 흐름은 완료, 검토중, 진행중, 계획 순서를 기본으로 하며 아래로 갈수록 미래 작업에 가까워지게 정렬한다.
|
||||||
|
|
||||||
|
## 구현 잠금
|
||||||
|
|
||||||
|
- `구현 잠금`은 승인 의식이 아니라 사용자 결정이 필요한지 표시하는 얇은 상태다.
|
||||||
|
- 제품 방향, 범위, 우선순위, 책임 경계처럼 사용자만 결정할 수 있는 항목이 남아 있으면 상태를 `잠금`으로 두고 `결정 필요` 체크리스트에 질문을 적는다.
|
||||||
|
- 기존 구조, 도메인 rule, 플랫폼 관례, 업계 표준으로 합리적으로 정할 수 있는 항목은 `결정 필요`가 아니라 `작업 컨텍스트`의 표준선이나 구현 가정으로 기록한다.
|
||||||
|
- Milestone 전체에서 사용자만 결정할 항목이 더 이상 없고 에이전트가 표준선에 따라 실행하면 되는 상태라면 `해제`로 둔다.
|
||||||
|
- 선택한 Milestone에 `구현 잠금` 섹션이 없거나 상태가 `잠금`이면 코드 구현, `agent-task` 구현 계획, 세부 API/파일 구조 확정을 시작하기 전에 현재 요청에 직접 영향을 주는 `결정 필요` 항목만 사용자에게 확인한다.
|
||||||
|
- 현재 요청과 직접 관련 없는 미정 항목은 잠금 상태로 남겨도 되며, 표준선으로 처리 가능한 작업을 막지 않는다.
|
||||||
|
- 잠금 상태를 바꾸더라도 `필수 기능`이나 `완료 기준`을 자동 완료 처리하지 않는다.
|
||||||
|
|
||||||
|
## Epic과 Task id
|
||||||
|
|
||||||
|
- Milestone 문서의 `필수 기능`은 Epic heading과 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>`를 판별하고, 상태 체크 후 `update-roadmap` 흐름으로 Milestone 업데이트를 호출한다.
|
||||||
|
- 런타임 완료 이벤트가 최종 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에서 follow-up plan/review를 이어간다.
|
||||||
|
|
||||||
|
## 완료 리뷰
|
||||||
|
|
||||||
|
- Task 완료나 Milestone 갱신 시 필수 Epic/Task와 완료 기준이 모두 evidence와 함께 `[x]`가 되었는지 확인한다.
|
||||||
|
- 모두 충족된 것으로 보이면 Milestone을 `[완료]`로 바로 바꾸거나 archive로 이동하지 말고 `[검토중]`으로 바꾼다.
|
||||||
|
- `[검토중]`으로 바꿀 때는 Milestone 문서에 `완료 리뷰` 섹션을 만들거나 갱신하고, 완료 근거 1~3줄과 사용자에게 필요한 최종 확인 항목을 남긴다.
|
||||||
|
- 사용자가 완료를 승인한 뒤에만 `[완료]`로 전환하고 archive 이동을 수행한다.
|
||||||
|
- Phase도 모든 하위 Milestone이 `[완료]` 또는 `[폐기]`로 정리되어 Phase 완료 후보가 되면 `[검토중]`으로 두고 사용자 최종 확인을 받은 뒤 `[완료]` 또는 `[폐기]`로 전환한다.
|
||||||
|
|
||||||
|
## 작업 지점 분석
|
||||||
|
|
||||||
|
- 현재 작업 지점이나 남은 작업 분석 요청은 `analyze-roadmap-position` 스킬로 처리한다.
|
||||||
|
- 분석 답변은 `agent-ops/skills/common/_templates/roadmap-position-report-template.md` 섹션과 필드 순서를 따른다.
|
||||||
|
- 이때 `current.md`만으로 단정하지 말고 코드, git 상태, diff, 활성 Phase, 활성 Milestone 문서를 함께 본다.
|
||||||
|
- Phase 또는 Milestone 후보가 여럿이면 단순 나열하지 말고 1순위와 2순위를 추천하고 근거를 함께 제시한다.
|
||||||
|
|
||||||
|
## 아카이브
|
||||||
|
|
||||||
|
- 완료 또는 폐기되어 현재 작업 후보에서 제외할 Phase/Milestone은 `update-roadmap` 스킬로 아카이빙한다.
|
||||||
|
- `[검토중]` Phase/Milestone은 archive 대상이 아니며, 사용자 승인 전까지 활성 경로에 남긴다.
|
||||||
|
- Phase 아카이브 대상은 `agent-ops/roadmap/archive/phase/<phase-slug>/PHASE.md`와 같은 scaffold로 이동한다.
|
||||||
|
- Milestone 아카이브 대상은 `agent-ops/roadmap/archive/phase/<phase-slug>/milestones/<milestone-slug>.md`로 이동한다.
|
||||||
|
- 아카이빙할 때는 활성 `ROADMAP.md` 또는 활성 `PHASE.md`에 archive 문서 링크와 짧은 요약만 남긴다.
|
||||||
|
- 아카이브된 Phase/Milestone은 `current.md`에 남기지 않고, 일반 Phase/Milestone 선택이나 위치 분석의 후보로 삼지 않는다.
|
||||||
|
- 아카이브 문서는 과거 기록 스냅샷으로 보고, 최신 템플릿이나 스킬 규약에 맞춰 재포맷하지 않는다.
|
||||||
30
agent-ops/rules/common/rules.md
Normal file
30
agent-ops/rules/common/rules.md
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# 공통 규칙
|
||||||
|
|
||||||
|
- **현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
|
||||||
|
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
|
||||||
|
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
|
||||||
|
- 요청 범위를 넘는 변경을 하지 않는다.
|
||||||
|
- 불확실하면 단정하지 말고 후보를 제시한다.
|
||||||
|
- `agent-task/archive/**`는 사용자가 명시적으로 요청한 경우에만 읽는다.
|
||||||
|
- `agent-ops/roadmap/` 디렉터리가 있는 프로젝트에서도 `agent-ops/roadmap/archive/**`는 일반 작업에서 읽지 않는다. 로드맵 과거 완료 내용, 완료 근거, 복원, 비교가 필요한 경우에만 `agent-ops/rules/common/rules-roadmap.md`의 archive 접근 규칙을 따른다.
|
||||||
|
- agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 `agent-ops/rules/common/philosophy.md`를 읽는다.
|
||||||
|
|
||||||
|
**세션 최초 1회 아래 파일을 순서대로 반드시 읽는다.** 파일이나 디렉터리가 없는 항목은 건너뛴다. 그외에 스킵은 금지한다.
|
||||||
|
|
||||||
|
1. `agent-ops/rules/project/rules.md`
|
||||||
|
2. `agent-ops/rules/private/rules.md`
|
||||||
|
3. `agent-ops/roadmap/` 디렉터리가 있으면 `agent-ops/rules/common/rules-roadmap.md`
|
||||||
|
|
||||||
|
# 스킬 규칙
|
||||||
|
|
||||||
|
**아래 경우에 부합되는지 반드시 끝까지 정독해서 읽고, 부합할 경우 `agent-ops/skills/common/router.md`를 작업 최초 1회 읽고 수행한다.** 자동으로 수행하지 않는다. **절대 스킵하지 말고 정독해야한다**
|
||||||
|
- agent-ops 초기화
|
||||||
|
- domain rule 생성
|
||||||
|
- skill 생성
|
||||||
|
- README 생성
|
||||||
|
- 로드맵/마일스톤 생성·갱신
|
||||||
|
- 현재 작업 지점 / 남은 작업 분석
|
||||||
|
- 계획 작성 / plan 생성
|
||||||
|
- 코드 리뷰 / review 진행
|
||||||
|
- git commit / push
|
||||||
|
- agent-ops 업데이트 / 진입 파일 재적용
|
||||||
61
agent-ops/rules/project/domain/android-push-runtime/rules.md
Normal file
61
agent-ops/rules/project/domain/android-push-runtime/rules.md
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
---
|
||||||
|
domain: android-push-runtime
|
||||||
|
last_rule_review_commit: 678302bc3ea1b8ad31b03bbe0b5f3630f7169555
|
||||||
|
last_rule_updated_at: 2026-05-25
|
||||||
|
---
|
||||||
|
|
||||||
|
# android-push-runtime
|
||||||
|
|
||||||
|
## 목적 / 책임
|
||||||
|
|
||||||
|
Android에서 Mattermost FCM payload를 수신해 ACK, 서명 검증, 데이터 보강, system notification 표시, tap/reply/dismiss 처리를 수행한다.
|
||||||
|
|
||||||
|
## 포함 경로
|
||||||
|
|
||||||
|
- `android/src/main/AndroidManifest.xml` — Firebase Messaging component 충돌 방지와 plugin service/receiver 등록을 포함한다.
|
||||||
|
- `android/src/main/kotlin/com/tokilabs/mattermost_push_plugin/` — Flutter plugin binding, FCM service, lifecycle tracking, launch intent, event dispatch를 포함한다.
|
||||||
|
- `android/src/main/kotlin/com/tokilabs/mattermost_push_plugin/helpers/` — DB, network, notification, bitmap, payload data helper를 포함한다.
|
||||||
|
- `android/src/main/kotlin/com/tokilabs/mattermost_push_plugin/helpers/db/` — Room database entity/DAO/schema를 포함한다.
|
||||||
|
- `android/src/main/java/com/tokilabs/mattermost_push_plugin/` — reply/dismiss receiver/service와 receipt delivery를 포함한다.
|
||||||
|
- `android/src/main/java/com/tokilabs/mattermost_push_plugin/helpers/` — notification builder와 signature verification helper를 포함한다.
|
||||||
|
- `android/src/main/res/` — notification icon/action assets를 포함한다.
|
||||||
|
- `android/src/test/` — Android native unit test를 포함한다.
|
||||||
|
- `android/build.gradle.kts`, `android/settings.gradle*` — Android library build and dependency contract를 포함한다.
|
||||||
|
|
||||||
|
## 제외 경로
|
||||||
|
|
||||||
|
- `lib/` — host-facing Dart API와 channel consumer 도메인이다.
|
||||||
|
- `ios/`, `macos/` — Apple scaffold 도메인이다.
|
||||||
|
- `example/` — plugin consumer 예제이며 native runtime 구현 소유가 아니다.
|
||||||
|
|
||||||
|
## 주요 구성 요소
|
||||||
|
|
||||||
|
- `MattermostPushPlugin` — Flutter engine attach, MethodChannel/EventChannel, lifecycle listener, intent payload 전달을 담당한다.
|
||||||
|
- `MattermostFirebaseMessagingService` — FCM token/message 수신과 push 처리 pipeline을 담당한다.
|
||||||
|
- `PushNotificationEvents` — Flutter attached state, event sink, pending event dispatch를 관리한다.
|
||||||
|
- `CustomPushNotificationHelper` — notification channel/builder/reply action/signature verification을 담당한다.
|
||||||
|
- `ReceiptDelivery`와 `Network` — ACK/reply HTTP 요청과 auth token storage를 담당한다.
|
||||||
|
- `DatabaseHelper`, `GlobalDatabase`, `MattermostDatabase` — device token, server mapping, Mattermost local data access를 담당한다.
|
||||||
|
- `NotificationReplyBroadcastReceiver`, `NotificationDismissService` — inline reply와 dismiss action을 처리한다.
|
||||||
|
|
||||||
|
## 유지할 패턴
|
||||||
|
|
||||||
|
- push pipeline 순서는 `server_url` 해석, ACK, signature verification, data fetch/store, notification posting, Flutter event dispatch 순서를 보존한다.
|
||||||
|
- signature verification 실패 시 notification posting과 Flutter message delivery를 진행하지 않는다.
|
||||||
|
- `firebase_messaging` 기본 receiver/service/provider 제거 manifest 설정을 보존한다.
|
||||||
|
- Room schema 변경 시 entity, DAO, database version, migration/fallback 정책을 함께 검토한다.
|
||||||
|
- Android notification permission `SecurityException`은 process crash로 번지지 않게 처리한다.
|
||||||
|
- coroutine/global state 변경은 service lifecycle과 Flutter engine attach 전후 상황을 고려한다.
|
||||||
|
|
||||||
|
## 다른 도메인과의 경계
|
||||||
|
|
||||||
|
- **dart-api**: native runtime은 channel event payload를 만들어 보내지만 host navigation callback 정책은 Dart API가 담당한다.
|
||||||
|
- **project-support**: README smoke checklist는 runtime 동작 검증 절차를 기록하지만 구현 변경은 Android runtime 도메인에서 한다.
|
||||||
|
- **apple-stubs**: Android-first 구현을 Apple scaffold로 자동 복제하지 않는다.
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- ACK나 signature verification 결과를 무시하고 무조건 notification을 표시하지 않는다.
|
||||||
|
- Mattermost payload key, token prefix, channel 이름을 Dart API와 동기화 없이 변경하지 않는다.
|
||||||
|
- Manifest에서 custom FCM service와 Flutter Firebase service 제거 설정을 동시에 깨지 않는다.
|
||||||
|
- local Room DB 접근 실패를 push service crash로 전파하지 않는다.
|
||||||
46
agent-ops/rules/project/domain/apple-stubs/rules.md
Normal file
46
agent-ops/rules/project/domain/apple-stubs/rules.md
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
---
|
||||||
|
domain: apple-stubs
|
||||||
|
last_rule_review_commit: 678302bc3ea1b8ad31b03bbe0b5f3630f7169555
|
||||||
|
last_rule_updated_at: 2026-05-25
|
||||||
|
---
|
||||||
|
|
||||||
|
# apple-stubs
|
||||||
|
|
||||||
|
## 목적 / 책임
|
||||||
|
|
||||||
|
iOS와 macOS plugin 등록 scaffold를 유지하고, 아직 구현되지 않은 Mattermost push 기능의 플랫폼 경계를 명확히 둔다.
|
||||||
|
|
||||||
|
## 포함 경로
|
||||||
|
|
||||||
|
- `ios/` — iOS Swift plugin scaffold, podspec, privacy manifest, assets placeholder를 포함한다.
|
||||||
|
- `macos/` — macOS Swift plugin scaffold, podspec, privacy manifest를 포함한다.
|
||||||
|
|
||||||
|
## 제외 경로
|
||||||
|
|
||||||
|
- `android/` — production-ready push runtime 도메인이다.
|
||||||
|
- `lib/` — cross-platform Dart public API 도메인이다.
|
||||||
|
- `example/` — host app integration 예제 도메인이다.
|
||||||
|
|
||||||
|
## 주요 구성 요소
|
||||||
|
|
||||||
|
- `ios/Classes/MattermostPushPlugin.swift` — iOS FlutterPlugin 등록과 `getPlatformVersion` stub을 제공한다.
|
||||||
|
- `macos/Classes/MattermostPushPlugin.swift` — macOS FlutterPlugin 등록과 `getPlatformVersion` stub을 제공한다.
|
||||||
|
- `PrivacyInfo.xcprivacy` — Apple platform privacy manifest scaffold를 유지한다.
|
||||||
|
|
||||||
|
## 유지할 패턴
|
||||||
|
|
||||||
|
- Apple platform은 현재 no-op scaffold임을 유지하고 Android 기능 parity를 암묵적으로 선언하지 않는다.
|
||||||
|
- Swift plugin channel 이름은 scaffold method channel과 Dart public API 확장 계획을 고려해 변경한다.
|
||||||
|
- podspec, privacy manifest, generated Runner/example 파일의 책임을 구분한다.
|
||||||
|
|
||||||
|
## 다른 도메인과의 경계
|
||||||
|
|
||||||
|
- **dart-api**: Dart API 변경이 Apple native 구현을 요구하면 stub 상태와 expected behavior를 함께 조정한다.
|
||||||
|
- **android-push-runtime**: Android runtime helper나 manifest 정책을 Apple 경로로 복사하지 않는다.
|
||||||
|
- **project-support**: README support matrix와 example 문서는 Apple scaffold 상태를 정확히 반영해야 한다.
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- iOS/macOS에서 구현되지 않은 push, reply, ACK, signing key 동작을 성공으로 가장하지 않는다.
|
||||||
|
- Android 전용 dependency나 manifest 개념을 Apple scaffold에 끌어오지 않는다.
|
||||||
|
- generated Xcode/example 산출물을 수동 편집 범위에 포함하지 않는다.
|
||||||
48
agent-ops/rules/project/domain/dart-api/rules.md
Normal file
48
agent-ops/rules/project/domain/dart-api/rules.md
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
---
|
||||||
|
domain: dart-api
|
||||||
|
last_rule_review_commit: 678302bc3ea1b8ad31b03bbe0b5f3630f7169555
|
||||||
|
last_rule_updated_at: 2026-05-25
|
||||||
|
---
|
||||||
|
|
||||||
|
# dart-api
|
||||||
|
|
||||||
|
## 목적 / 책임
|
||||||
|
|
||||||
|
Flutter host app이 사용하는 public API, native channel 계약, notification/opened event parsing, token callback 흐름을 담당한다.
|
||||||
|
|
||||||
|
## 포함 경로
|
||||||
|
|
||||||
|
- `lib/` — package export, singleton API, EventChannel/MethodChannel, event model, push type 상수를 포함한다.
|
||||||
|
- `test/` — Dart API와 event parsing, channel contract 테스트를 포함한다.
|
||||||
|
|
||||||
|
## 제외 경로
|
||||||
|
|
||||||
|
- `android/` — native FCM 수신, 알림 표시, Room/OkHttp/JJWT 처리는 Android runtime 도메인이다.
|
||||||
|
- `ios/`, `macos/` — 현재 no-op Swift scaffold 도메인이다.
|
||||||
|
- `example/` — host integration 예제와 manual smoke 지원 도메인이다.
|
||||||
|
|
||||||
|
## 주요 구성 요소
|
||||||
|
|
||||||
|
- `MattermostPushPlugin` — singleton public API, native event stream, action method channel, navigation/device-token callback을 관리한다.
|
||||||
|
- `NotificationOpenedEvent` — native payload를 host navigation에 필요한 Dart model로 변환한다.
|
||||||
|
- `PushNotificationType` — native와 공유하는 event type 문자열 상수를 제공한다.
|
||||||
|
|
||||||
|
## 유지할 패턴
|
||||||
|
|
||||||
|
- channel 이름은 native Android `MattermostPushPlugin` companion object 상수와 동일해야 한다.
|
||||||
|
- native payload key는 snake_case를 유지하고 Dart model에서 임의로 camelCase key로 바꾸지 않는다.
|
||||||
|
- token refresh는 저장 channel 호출 후 `onDeviceTokenReady`에 `android_rn-v2:` prefix 포함 값을 전달한다.
|
||||||
|
- `onNotification` raw stream은 처리된 모든 native event를 host app에 전달한다.
|
||||||
|
|
||||||
|
## 다른 도메인과의 경계
|
||||||
|
|
||||||
|
- **android-push-runtime**: Dart API는 native method/event 계약만 다루고 FCM 수신, ACK, 서명 검증, notification rendering 정책을 구현하지 않는다.
|
||||||
|
- **project-support**: example app은 Dart API 사용 예시를 검증하지만 public API 계약 자체는 `lib/`와 `test/`에서 관리한다.
|
||||||
|
- **apple-stubs**: Apple scaffold가 기능을 구현하기 전까지 Dart API에서 플랫폼별 native 성공을 가정하지 않는다.
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- Android native channel 이름이나 method 이름을 Dart 쪽에서만 변경하지 않는다.
|
||||||
|
- Mattermost payload key를 host-facing model 밖에서 임의 변환하지 않는다.
|
||||||
|
- stream controller가 닫힌 뒤 event를 add하도록 변경하지 않는다.
|
||||||
|
- Android 전용 token prefix 정책을 플랫폼 공통 동작으로 확장하지 않는다.
|
||||||
51
agent-ops/rules/project/domain/project-support/rules.md
Normal file
51
agent-ops/rules/project/domain/project-support/rules.md
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
---
|
||||||
|
domain: project-support
|
||||||
|
last_rule_review_commit: 678302bc3ea1b8ad31b03bbe0b5f3630f7169555
|
||||||
|
last_rule_updated_at: 2026-05-25
|
||||||
|
---
|
||||||
|
|
||||||
|
# project-support
|
||||||
|
|
||||||
|
## 목적 / 책임
|
||||||
|
|
||||||
|
패키지 메타데이터, 문서, Flutter analysis 설정, example app, smoke/integration 검증 흐름을 관리한다.
|
||||||
|
|
||||||
|
## 포함 경로
|
||||||
|
|
||||||
|
- `pubspec.yaml` — package metadata, Flutter plugin platform mapping, Dart/Flutter dependency contract를 포함한다.
|
||||||
|
- `analysis_options.yaml` — Dart analysis/lint 설정을 포함한다.
|
||||||
|
- `README.md`, `CHANGELOG.md` — support matrix, API usage, host integration 책임, manual smoke checklist를 포함한다.
|
||||||
|
- `example/` — plugin consumer app scaffold와 integration/widget test를 포함한다.
|
||||||
|
- `.metadata`, root project files — Flutter package scaffold metadata를 포함한다.
|
||||||
|
|
||||||
|
## 제외 경로
|
||||||
|
|
||||||
|
- `lib/` — public Dart API 구현 도메인이다.
|
||||||
|
- `android/src/main/` — Android native runtime 구현 도메인이다.
|
||||||
|
- `ios/`, `macos/` — Apple scaffold 도메인이다.
|
||||||
|
|
||||||
|
## 주요 구성 요소
|
||||||
|
|
||||||
|
- `README.md` — plugin 책임, platform support, host app integration, manual smoke checklist의 기준 문서다.
|
||||||
|
- `example/lib/main.dart` — consumer-side API 사용과 manual verification 보조 화면을 제공한다.
|
||||||
|
- `example/integration_test/` — host integration 흐름 검증 scaffold를 둔다.
|
||||||
|
- `pubspec.yaml` — plugin platform registration과 dependency version을 관리한다.
|
||||||
|
|
||||||
|
## 유지할 패턴
|
||||||
|
|
||||||
|
- README support matrix는 실제 구현 상태와 맞춘다. Android는 production-ready, iOS/macOS는 no-op scaffold로 명시한다.
|
||||||
|
- dependency 변경은 Flutter/Dart API, Android Gradle dependency, example app 영향을 함께 확인한다.
|
||||||
|
- generated build output, `.dart_tool`, Gradle build cache, IDE workspace 파일은 수동 변경 대상으로 삼지 않는다.
|
||||||
|
- manual smoke checklist는 headless test로 검증되지 않는 FCM/notification/reply/ACK 흐름을 보완한다.
|
||||||
|
|
||||||
|
## 다른 도메인과의 경계
|
||||||
|
|
||||||
|
- **dart-api**: example과 문서는 public API 사용 방식을 보여주되 API 계약 변경은 `lib/`와 테스트에서 확정한다.
|
||||||
|
- **android-push-runtime**: support 문서는 Android runtime의 실제 동작을 반영하지만 native helper 구현은 수정하지 않는다.
|
||||||
|
- **apple-stubs**: support matrix와 platform 설명은 Apple scaffold의 no-op 상태를 과장하지 않는다.
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- build/generated 산출물을 의도된 소스 변경처럼 커밋하지 않는다.
|
||||||
|
- 문서에서 자동화되지 않은 FCM end-to-end 검증을 테스트 완료로 단정하지 않는다.
|
||||||
|
- package metadata 변경 시 example lock/build 상태만 보고 dependency 호환성을 단정하지 않는다.
|
||||||
52
agent-ops/rules/project/rules.md
Normal file
52
agent-ops/rules/project/rules.md
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
# mattermost_push_plugin 프로젝트 규칙
|
||||||
|
|
||||||
|
## 응답 언어
|
||||||
|
|
||||||
|
- 기본 응답은 한국어로 한다.
|
||||||
|
- 코드 식별자, 파일 경로, API 이름, 플랫폼 용어는 원문 표기를 유지한다.
|
||||||
|
|
||||||
|
## 프로젝트 개요
|
||||||
|
|
||||||
|
- Mattermost push notification을 처리하는 Android-first Flutter plugin이다.
|
||||||
|
- Dart 공개 API는 host app과 native Android runtime 사이의 channel/stream 계약을 제공한다.
|
||||||
|
- Android runtime은 FCM 수신, 서명 검증, 알림 표시, inline reply, dismiss, ACK 전송, Room 기반 로컬 저장을 담당한다.
|
||||||
|
- iOS와 macOS는 현재 no-op scaffold이며, Android 기능 parity를 임의로 가정하지 않는다.
|
||||||
|
|
||||||
|
## 기술 스택
|
||||||
|
|
||||||
|
- Flutter / Dart package, `firebase_messaging`
|
||||||
|
- Android Gradle Plugin, Kotlin, Java, AndroidX, Room, OkHttp, JJWT, Firebase Messaging
|
||||||
|
- iOS UIKit Swift plugin scaffold
|
||||||
|
- macOS FlutterMacOS Swift plugin scaffold
|
||||||
|
- 테스트: `flutter test`, Android unit test, example integration test scaffold
|
||||||
|
|
||||||
|
## 프로젝트 특화 컨벤션
|
||||||
|
|
||||||
|
- Dart channel 이름은 native Android의 `MattermostPushPlugin.CHANNEL_EVENTS`, `CHANNEL_ACTIONS`와 항상 맞춘다.
|
||||||
|
- FCM token은 Dart API에서 `android_rn-v2:` prefix를 붙인 값으로 저장하고 host callback에 전달한다.
|
||||||
|
- native payload key는 Mattermost/React Native 호환 snake_case key를 유지한다. 예: `server_url`, `channel_id`, `root_id`, `is_crt_enabled`, `ack_id`.
|
||||||
|
- Android push 처리에서 `server_url`이 payload에 없으면 저장된 server identifier와 단일 서버 fallback 순서로 해석한다.
|
||||||
|
- 서명 검증 실패는 알림 표시 전에 중단한다. backward compatibility 예외는 기존 helper의 조건을 유지한다.
|
||||||
|
- `firebase_messaging` 기본 Android service/receiver/provider 제거 manifest 설정은 중복 FCM 처리 방지를 위한 핵심 계약이다.
|
||||||
|
- iOS/macOS 변경은 현재 scaffold 상태를 명시하고, Android 전용 기능을 public Dart API에서 무조건 성공으로 보이게 만들지 않는다.
|
||||||
|
- build output, IDE 설정, generated Flutter/Gradle 산출물은 수정 범위에 포함하지 않는다.
|
||||||
|
|
||||||
|
## 검증 기준
|
||||||
|
|
||||||
|
- Dart API나 event parsing 변경 시 `flutter test`를 우선 실행한다.
|
||||||
|
- Android native runtime 변경 시 가능하면 `cd android && ./gradlew testDebugUnitTest` 또는 관련 unit test를 실행한다.
|
||||||
|
- FCM 수신, system notification, inline reply, ACK delivery, tap navigation은 headless 자동화가 어려우므로 README의 manual smoke checklist와 연결해 변경 위험을 기록한다.
|
||||||
|
- channel 이름, payload key, token format 변경은 Dart test와 native 코드 양쪽을 함께 확인한다.
|
||||||
|
|
||||||
|
## 도메인 매핑
|
||||||
|
|
||||||
|
| 경로 패턴 | 도메인 | rules.md |
|
||||||
|
|----------|--------|----------|
|
||||||
|
| `lib/**`, `test/**` | dart-api | `agent-ops/rules/project/domain/dart-api/rules.md` |
|
||||||
|
| `android/src/main/**`, `android/src/test/**`, `android/build.gradle.kts`, `android/settings.gradle*` | android-push-runtime | `agent-ops/rules/project/domain/android-push-runtime/rules.md` |
|
||||||
|
| `ios/**`, `macos/**` | apple-stubs | `agent-ops/rules/project/domain/apple-stubs/rules.md` |
|
||||||
|
| `example/**`, `pubspec.yaml`, `analysis_options.yaml`, `README.md`, `CHANGELOG.md` | project-support | `agent-ops/rules/project/domain/project-support/rules.md` |
|
||||||
|
|
||||||
|
## 스킬 라우팅
|
||||||
|
|
||||||
|
현재 프로젝트 전용 skill은 없다. 반복 작업이 안정화되면 `agent-ops/skills/project/<skill-name>/SKILL.md`를 추가한다.
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
# 현재 로드맵 컨텍스트
|
||||||
|
|
||||||
|
## 활성 Phase
|
||||||
|
|
||||||
|
- [<계획 | 진행중 | 검토중 | 보류>] <phase-name>
|
||||||
|
- 경로: `agent-ops/roadmap/phase/<phase-slug>/PHASE.md`
|
||||||
|
|
||||||
|
## 활성 Milestone
|
||||||
|
|
||||||
|
- [<계획 | 진행중 | 검토중 | 보류>] <milestone-name>
|
||||||
|
- Phase: `agent-ops/roadmap/phase/<phase-slug>/PHASE.md`
|
||||||
|
- 경로: `agent-ops/roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md`
|
||||||
|
|
||||||
|
## 선택 규칙
|
||||||
|
|
||||||
|
- 이 문서는 활성 Phase와 활성 Milestone 후보 목록이며, 개인별 현재 작업 위치나 완료 상태를 기록하지 않는다.
|
||||||
|
- 활성 Phase는 `agent-ops/roadmap/phase/<phase-slug>/PHASE.md`를 가리킨다.
|
||||||
|
- 활성 Milestone은 `agent-ops/roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md`를 가리킨다.
|
||||||
|
- 활성 항목은 아카이브 경로를 포함하지 않는다.
|
||||||
|
- `[검토중]` 항목은 사용자 완료 확인 전까지 활성 항목으로 남길 수 있다.
|
||||||
|
- `[완료]` 또는 `[폐기]` 항목은 archive 링크를 남긴 뒤 활성 항목에서 제거한다.
|
||||||
|
- 요청 내용, 현재 브랜치, 변경 파일, 관련 코드 경로를 보고 가장 관련 있는 Phase와 Milestone을 선택하고 같은 세션에서 1회 읽는다.
|
||||||
|
- 활성 Phase 또는 Milestone 둘 이상에 걸치면 필요한 문서를 모두 읽고 작업 범위를 좁힌다.
|
||||||
|
- 활성 범위 밖의 작업이면 `agent-ops/roadmap/ROADMAP.md`의 Phase 흐름을 확인하고 사용자에게 진행 또는 전환 여부를 확인한다.
|
||||||
|
- 완료된 과거 내용이 필요할 때만 `ROADMAP.md` 또는 `PHASE.md`에 있는 archive 링크를 따라가서 읽는다.
|
||||||
|
- 선택된 Milestone의 `구현 잠금` 섹션이 없거나 상태가 `잠금`이면 구현이나 구현 계획을 시작하기 전에 현재 요청에 직접 영향을 주는 `결정 필요` 항목만 확인한다. 관련 결정이 없고 표준선으로 처리 가능하면 잠금을 유지한 채 진행할 수 있으며, Milestone 전체에서 사용자만 결정할 항목이 더 이상 없을 때만 `구현 잠금` 상태를 `해제`로 둔다.
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
# Milestone: <Milestone 이름>
|
||||||
|
|
||||||
|
## 위치
|
||||||
|
|
||||||
|
- Roadmap: `agent-ops/roadmap/ROADMAP.md`
|
||||||
|
- Phase: `agent-ops/roadmap/phase/<phase-slug>/PHASE.md`
|
||||||
|
|
||||||
|
## 목표
|
||||||
|
|
||||||
|
<이 Milestone이 끝났을 때 달성되어야 하는 결과를 1~3문장으로 작성>
|
||||||
|
|
||||||
|
## 상태
|
||||||
|
|
||||||
|
[<계획 | 진행중 | 검토중 | 완료 | 보류 | 폐기>]
|
||||||
|
|
||||||
|
## 구현 잠금
|
||||||
|
|
||||||
|
- 상태: <잠금 | 해제>
|
||||||
|
- 결정 필요: <없음 | 아래 체크리스트>
|
||||||
|
- [ ] <사용자만 결정할 수 있는 제품/범위/우선순위/책임 경계 질문>
|
||||||
|
|
||||||
|
## 범위
|
||||||
|
|
||||||
|
- <이 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를 다시 사용할 수 있다.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Epic: [epic-id] <Epic 이름>
|
||||||
|
|
||||||
|
<이 Epic이 묶는 capability 또는 산출물 설명>
|
||||||
|
|
||||||
|
- [ ] [item-id] <구현 세부가 아니라 이 Milestone에서 달성해야 할 capability 또는 산출물>
|
||||||
|
|
||||||
|
## 완료 기준
|
||||||
|
|
||||||
|
- [ ] <완료 여부를 확인할 수 있는 기준>
|
||||||
|
|
||||||
|
## 완료 리뷰
|
||||||
|
|
||||||
|
- 상태: <없음 | 요청됨 | 승인됨 | 보완 필요 | 보류 | 폐기>
|
||||||
|
- 요청일: <YYYY-MM-DD | 없음>
|
||||||
|
- 완료 근거: <모든 필수 Task와 완료 기준 충족 여부를 1~3줄로 요약>
|
||||||
|
- 리뷰 필요:
|
||||||
|
- [ ] 사용자가 완료 결과를 확인했다
|
||||||
|
- [ ] archive 이동을 승인했다
|
||||||
|
- 리뷰 코멘트: <없음 | 보완/보류/폐기 방향성>
|
||||||
|
|
||||||
|
## 범위 제외
|
||||||
|
|
||||||
|
- <이 Milestone에서 의도적으로 하지 않는 일>
|
||||||
|
|
||||||
|
## 작업 컨텍스트
|
||||||
|
|
||||||
|
- 관련 경로: `<path>`
|
||||||
|
- 표준선(선택): <기존 구조, 도메인 rule, 플랫폼 관례, 업계 표준으로 진행할 기본 기준>
|
||||||
|
- 선행 작업: <없음 또는 Milestone/태스크 이름>
|
||||||
|
- 후속 작업: <없음 또는 Milestone/태스크 이름>
|
||||||
|
- 확인 필요: <!-- TODO: 확인 필요 -->
|
||||||
22
agent-ops/skills/common/_templates/roadmap-phase-template.md
Normal file
22
agent-ops/skills/common/_templates/roadmap-phase-template.md
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Phase: <Phase 이름>
|
||||||
|
|
||||||
|
## 상태
|
||||||
|
|
||||||
|
[<계획 | 진행중 | 검토중 | 완료 | 보류 | 폐기>]
|
||||||
|
|
||||||
|
## 목표
|
||||||
|
|
||||||
|
<이 Phase가 끝났을 때 달성되어야 하는 결과와 책임 경계를 1~3문장으로 작성>
|
||||||
|
|
||||||
|
## Milestone 흐름
|
||||||
|
|
||||||
|
완료된 Milestone은 archive 경로를 가리키고, 검토중, 진행중, 계획 또는 보류 Milestone은 이 Phase 하위 `milestones/` 경로를 가리킨다.
|
||||||
|
완료, 검토중, 진행중, 계획 순서로 두어 아래로 갈수록 미래 작업에 가까워지게 정렬한다.
|
||||||
|
|
||||||
|
- [<계획 | 진행중 | 검토중 | 완료 | 보류 | 폐기>] <Milestone 이름>
|
||||||
|
- 경로: `agent-ops/roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md` 또는 `agent-ops/roadmap/archive/phase/<phase-slug>/milestones/<milestone-slug>.md`
|
||||||
|
- 요약: <목표 또는 결과 1문장>
|
||||||
|
|
||||||
|
## Phase 경계
|
||||||
|
|
||||||
|
- <이 Phase에서 유지할 책임 경계 또는 범위 제외 기준>
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
# 현재 작업 분석
|
||||||
|
|
||||||
|
- 추정 Phase: <phase-name 또는 복수 후보>
|
||||||
|
- 추정 Milestone: <milestone-name 또는 복수 후보>
|
||||||
|
- Phase 링크: [<phase-name>](agent-ops/roadmap/phase/<phase-slug>/PHASE.md)
|
||||||
|
- Milestone 링크: [<milestone-name>](agent-ops/roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md)
|
||||||
|
- 우선순위 추천: <단일 후보 | 1순위: phase/milestone; 2순위: phase/milestone; 추천 근거>
|
||||||
|
- 신뢰도: <높음 | 중간 | 낮음>
|
||||||
|
- 구현 잠금: <해제 | 잠금 | 정보 없음>
|
||||||
|
- 완료 리뷰: <없음 | 요청됨 | 보완 필요 | 승인됨 | 보류 | 폐기 | 정보 없음>
|
||||||
|
- 결정 필요: <없음 | 현재 요청에 직접 영향을 주는 사용자 결정 항목 요약>
|
||||||
|
- 한 줄 결론: <현재 작업 지점과 가장 중요한 다음 판단을 1문장으로 요약>
|
||||||
|
|
||||||
|
## 판단 근거
|
||||||
|
|
||||||
|
- 브랜치: <branch-name 또는 확인 불가>
|
||||||
|
- 변경 파일: <없음 | N개, 핵심 경로 요약>
|
||||||
|
- 로드맵 근거: <Milestone 목표/범위/필수 기능/완료 기준과 연결된 근거>
|
||||||
|
- 코드/테스트 근거: <코드, 테스트, diff, 문서에서 확인한 근거>
|
||||||
|
|
||||||
|
## 후보 우선순위
|
||||||
|
|
||||||
|
- 1순위: <단일 후보 또는 가장 먼저 봐야 할 Phase/Milestone과 이유>
|
||||||
|
- 2순위: <없음 또는 다음으로 봐야 할 Phase/Milestone과 이유>
|
||||||
|
- 낮은 우선순위/보류: <없음 또는 후보에서 밀린 Phase/Milestone과 이유>
|
||||||
|
|
||||||
|
## 구현된 것으로 보이는 부분
|
||||||
|
|
||||||
|
- 확인됨: [<epic-id 또는 해당 없음>] [<item-id 또는 해당 없음>] <코드/문서/테스트 근거가 있는 완료 후보>
|
||||||
|
|
||||||
|
## 남은 작업
|
||||||
|
|
||||||
|
- 확인됨: [<epic-id 또는 신규 id 필요>] [<item-id 또는 신규 id 필요>] <코드/문서/테스트 근거로 남았다고 볼 수 있는 작업>
|
||||||
|
- 추정됨: [<epic-id 또는 신규 id 필요>] [<item-id 또는 신규 id 필요>] <구조상 필요해 보이나 추가 확인이 필요한 작업>
|
||||||
|
- 확인 필요: [<epic-id 또는 신규 id 필요>] [<item-id 또는 신규 id 필요>] <사용자 판단, 범위 결정, 제품 의도가 필요한 작업>
|
||||||
|
|
||||||
|
## 위험/불확실성
|
||||||
|
|
||||||
|
- <없음 또는 신뢰도를 낮춘 이유, 누락된 근거, 잠금/링크/템플릿 문제>
|
||||||
|
|
||||||
|
## 다음 행동
|
||||||
|
|
||||||
|
- 우선순위 1: <가장 먼저 할 작업 또는 확인>
|
||||||
|
- 우선순위 2: <다음 작업 또는 확인>
|
||||||
|
- 사용자 확인 필요: <없음 또는 현재 요청에 직접 영향을 주는 사용자 결정 질문>
|
||||||
|
|
||||||
|
## 읽은 주요 파일
|
||||||
|
|
||||||
|
- <path>
|
||||||
38
agent-ops/skills/common/_templates/roadmap-template.md
Normal file
38
agent-ops/skills/common/_templates/roadmap-template.md
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
# 로드맵
|
||||||
|
|
||||||
|
## 전체 목표
|
||||||
|
|
||||||
|
<프로젝트가 최종적으로 달성하려는 결과를 1~3문장으로 작성>
|
||||||
|
|
||||||
|
## Phase 흐름
|
||||||
|
|
||||||
|
위에서 아래로 진행된 순서와 예정 흐름을 나타낸다.
|
||||||
|
완료된 Phase도 로드맵에서 제거하지 않고, archive의 Phase 문서로 연결한다.
|
||||||
|
검토중 또는 진행중 Phase는 계획 Phase보다 위에 두어, 아래로 갈수록 미래 계획에 가까워지게 정렬한다.
|
||||||
|
|
||||||
|
- [<계획 | 진행중 | 검토중 | 완료 | 보류 | 폐기>] <Phase 이름>
|
||||||
|
- 경로: `agent-ops/roadmap/phase/<phase-slug>/PHASE.md` 또는 `agent-ops/roadmap/archive/phase/<phase-slug>/PHASE.md`
|
||||||
|
- 요약: <이 Phase의 목표와 역할 1문장>
|
||||||
|
|
||||||
|
## 로딩 정책
|
||||||
|
|
||||||
|
- 일반 작업에서는 `agent-ops/roadmap/ROADMAP.md`를 매번 읽지 않는다.
|
||||||
|
- 기능 추가, 구조 변경, 스킬 추가/수정, 문서 구조 변경 작업을 수행할 때는 `agent-ops/roadmap/current.md`를 먼저 읽는다.
|
||||||
|
- `current.md`는 현재 작업 위치가 아니라 활성 Phase와 활성 Milestone 후보 목록이다.
|
||||||
|
- `current.md`에는 개인별 현재 작업 위치나 완료 상태를 기록하지 않는다.
|
||||||
|
- `current.md`의 활성 Phase는 `agent-ops/roadmap/phase/<phase-slug>/PHASE.md`를 가리킨다.
|
||||||
|
- `current.md`의 활성 Milestone은 `agent-ops/roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md`를 가리킨다.
|
||||||
|
- `current.md`는 `agent-ops/roadmap/archive/**` 경로를 활성 항목으로 포함하지 않는다.
|
||||||
|
- 요청 내용, 현재 브랜치, 변경 파일, 관련 코드 경로를 보고 가장 관련 있는 활성 Phase와 Milestone 문서를 같은 세션에서 1회 읽는다.
|
||||||
|
- 활성 Phase 또는 Milestone 밖의 작업이면 이 문서의 Phase 흐름을 확인하고 사용자에게 진행 또는 전환 여부를 확인한다.
|
||||||
|
- 이 문서는 로드맵 생성/갱신, Phase 전환, Phase 추가/수정, 전체 구조 변경 요청이 있을 때만 읽는다.
|
||||||
|
- 상세 작업과 완료 기준은 각 Milestone 문서의 `필수 기능`, `완료 기준`으로 관리한다.
|
||||||
|
- 모든 필수 작업과 완료 기준이 충족된 Milestone은 먼저 `[검토중]`으로 두고, 사용자 완료 확인과 archive 승인을 받은 뒤 `[완료]`로 전환한다.
|
||||||
|
- 완료된 Phase는 `agent-ops/roadmap/archive/phase/<phase-slug>/PHASE.md`로 이동하고, 하위 Milestone도 같은 archive Phase scaffold 아래에 둔다.
|
||||||
|
- 진행중 Phase 안에서 완료된 Milestone은 활성 Phase 문서에 짧은 링크를 남기고, 상세 문서는 `agent-ops/roadmap/archive/phase/<phase-slug>/milestones/`로 이동한다.
|
||||||
|
- archive `PHASE.md`는 Phase 자체가 완료 또는 폐기될 때만 만들며, 진행중 Phase의 완료 Milestone만 archive된 경우 archive Phase 디렉터리에 `milestones/`만 있을 수 있다.
|
||||||
|
- `agent-ops/roadmap/archive/**`는 일반 작업에서 읽지 않는다. 과거 완료 내용, 완료 근거, 복원, 비교가 필요한 경우에만 `ROADMAP.md` 또는 `PHASE.md`의 archive 링크를 따라가서 읽는다.
|
||||||
|
- 아카이브된 Phase/Milestone 문서는 최신 템플릿이나 스킬 규약에 맞춰 재포맷하지 않는다.
|
||||||
|
- 선택된 Milestone의 `구현 잠금` 섹션이 없거나 상태가 `잠금`이면 코드 구현, `agent-task` 구현 계획 생성, 세부 API/파일 구조 확정을 시작하기 전에 현재 요청에 직접 영향을 주는 `결정 필요` 항목만 확인한다.
|
||||||
|
- 현재 요청과 직접 관련 없는 미정 항목은 잠금 상태로 남겨도 되며, 기존 구조/도메인 rule/플랫폼 관례로 정할 수 있는 작업은 표준선으로 기록하고 진행할 수 있다.
|
||||||
|
- 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>
|
||||||
|
- 검증 실패 시: <실패 시 취할 행동 — 롤백, 사용자 알림, 재시도 등>
|
||||||
|
|
||||||
|
## 출력 형식
|
||||||
|
|
||||||
|
```
|
||||||
|
<출력 예시>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- <절대 하면 안 되는 것>
|
||||||
|
- <절대 하면 안 되는 것>
|
||||||
116
agent-ops/skills/common/analyze-roadmap-position/SKILL.md
Normal file
116
agent-ops/skills/common/analyze-roadmap-position/SKILL.md
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
---
|
||||||
|
name: analyze-roadmap-position
|
||||||
|
version: 1.9.0
|
||||||
|
description: "지금 작업이 뭐지?, 현재 작업 분석, 남은 작업 확인 요청에 대해 로드맵이 있으면 활성 Phase/Milestone과 코드 상태를 함께 읽고, 로드맵이 없으면 git/active task 기준으로 현재 작업 지점과 남은 일을 추정하는 읽기 전용 스킬"
|
||||||
|
---
|
||||||
|
|
||||||
|
# 작업 지점 분석
|
||||||
|
|
||||||
|
## 목적
|
||||||
|
|
||||||
|
현재 브랜치, 변경 파일, 코드 구조를 분석하고, 로드맵이 있으면 활성 Phase와 활성 Milestone 문서를 함께 읽어 지금 작업이 어느 Phase/Milestone에 걸쳐 있는지와 남은 작업 후보를 보고한다.
|
||||||
|
로드맵이 있으면 결과에는 추정한 Phase와 Milestone의 문서 링크를 함께 출력한다.
|
||||||
|
Phase나 Milestone 후보가 여럿이면 가장 먼저 볼 후보와 다음 후보를 추천하고, 추천 근거를 짧게 남긴다.
|
||||||
|
Milestone의 `필수 기능`에 Epic/Task id가 있으면 남은 작업과 판단 근거에 함께 표시해 사용자가 짧은 id로 후속 지시를 할 수 있게 한다.
|
||||||
|
`current.md`만 보고 현재 작업 위치를 단정하지 않고, 실제 코드 상태와 요청 내용을 근거로 판단한다.
|
||||||
|
`agent-ops/roadmap/` 디렉터리 또는 `current.md`가 없으면 로드맵 분석을 건너뛰고 git 상태, active `agent-task`, 요청 문장을 기준으로만 보고한다.
|
||||||
|
|
||||||
|
## 언제 호출할지
|
||||||
|
|
||||||
|
- 사용자가 "지금 작업이 뭐지?", "현재 작업이 뭐야?", "어디까지 했지?"라고 물을 때
|
||||||
|
- 사용자가 현재 브랜치 또는 변경 파일 기준으로 남은 작업을 알고 싶어 할 때
|
||||||
|
- 활성 Phase/Milestone 안에서 이번 요청이 어느 범위에 속하는지 확인해야 할 때
|
||||||
|
- 구현 전에 로드맵 기준 작업 위치를 가볍게 점검해야 할 때
|
||||||
|
|
||||||
|
## 먼저 확인할 것
|
||||||
|
|
||||||
|
- [ ] `agent-ops/skills/common/_templates/roadmap-position-report-template.md`를 읽어 최신 답변 템플릿 확인
|
||||||
|
- [ ] `agent-ops/roadmap/` 디렉터리 존재 여부 확인
|
||||||
|
- [ ] `agent-ops/roadmap/current.md` 존재 여부 확인
|
||||||
|
- [ ] 로드맵이 있으면 `current.md`의 활성 Phase와 활성 Milestone 목록이 가리키는 문서 존재 여부 확인
|
||||||
|
- [ ] 로드맵이 있으면 활성 항목이 `agent-ops/roadmap/archive/**` 경로를 가리키지 않는지 확인
|
||||||
|
- [ ] 로드맵이 있으면 활성 Phase/Milestone 이름과 문서 경로를 결과 출력에 쓸 Markdown 링크로 기록
|
||||||
|
- [ ] git 저장소이면 현재 브랜치, `git status --short`, 변경 파일 목록 확인
|
||||||
|
- [ ] 변경 파일이 있으면 `agent-ops/rules/project/rules.md`의 도메인 매핑 기준으로 관련 domain rule 확인
|
||||||
|
|
||||||
|
## 실행 절차
|
||||||
|
|
||||||
|
1. **활성 창 확인**
|
||||||
|
- `agent-ops/roadmap/` 디렉터리가 없으면 `ROADMAP.md`, `current.md`, Phase, Milestone, archive 문서를 읽지 않고 로드맵 없음으로 기록한 뒤 작업 흔적 확인으로 넘어간다. 이 경우 아래 로드맵 읽기 단계는 수행하지 않는다.
|
||||||
|
- `agent-ops/roadmap/current.md`가 없으면 `ROADMAP.md`를 자동으로 읽지 않는다. 로드맵 컨텍스트는 `없음` 또는 `확인 불가`로 기록하고 작업 흔적 확인으로 넘어간다. 이 경우 아래 로드맵 읽기 단계는 수행하지 않는다.
|
||||||
|
- `agent-ops/roadmap/current.md`를 읽고 활성 Phase, 활성 Milestone 후보와 선택 규칙을 파악한다.
|
||||||
|
- `current.md`의 후보가 `agent-ops/roadmap/archive/**`를 가리키면 해당 문서는 읽지 말고 로드맵 갱신 필요 항목으로 기록한다.
|
||||||
|
- 관련 활성 Phase 문서를 읽고 Phase 목표, Milestone 흐름, Phase 경계를 확인한다.
|
||||||
|
- 관련 활성 Milestone 문서를 읽고 목표, 범위, 필수 기능, 완료 기준, 완료 리뷰, 범위 제외, 구현 잠금을 확인한다.
|
||||||
|
- 목록이 많으면 사용자 요청이나 변경 파일과 관련 높은 Phase/Milestone부터 읽는다.
|
||||||
|
- `current.md` 형식이 맞지 않으면 `ROADMAP.md`를 자동으로 읽지 말고 로드맵 컨텍스트 불확실성을 보고한다.
|
||||||
|
|
||||||
|
2. **작업 흔적 확인**
|
||||||
|
- git 저장소이면 `git branch --show-current`, `git status --short`, `git diff --name-only`, 필요 시 `git diff --stat`을 확인한다.
|
||||||
|
- 변경 파일이 없으면 사용자의 요청 문장과 최근 대상 경로 힌트를 기준으로 추정한다.
|
||||||
|
- 변경 파일이 있으면 관련 코드와 테스트 파일을 필요한 만큼만 읽는다.
|
||||||
|
|
||||||
|
3. **Phase/Milestone 매칭**
|
||||||
|
- 로드맵이 없거나 `current.md`가 없으면 Phase/Milestone을 추정하지 않는다. `추정 Phase`, `추정 Milestone`, 문서 링크는 `없음`으로 기록하고 아래 Phase/Milestone 비교 항목은 수행하지 않는다.
|
||||||
|
- 활성 Phase의 목표/경계와 변경 파일/요청 내용을 비교한다.
|
||||||
|
- 활성 Milestone의 목표, 범위, 완료 기준, 범위 제외 항목과 변경 파일/요청 내용을 비교한다.
|
||||||
|
- Milestone의 `필수 기능`에서 관련 Epic/Task id가 있으면 판단 근거와 남은 작업에 함께 기록한다.
|
||||||
|
- 여러 Milestone 후보에서 같은 epic-id 또는 item-id가 보이면 id만으로 위치를 확정하지 말고 Milestone 이름과 문서 링크를 함께 제시한다.
|
||||||
|
- 활성 Milestone의 `구현 잠금` 섹션, 상태, `완료 리뷰` 섹션, `결정 필요` 항목을 함께 확인한다.
|
||||||
|
- 하나의 Milestone에 명확히 속하면 단일 후보로 보고한다.
|
||||||
|
- 둘 이상의 Phase 또는 Milestone에 걸치면 복수 후보로 보고하고, 어떤 파일이나 기능이 어느 후보에 닿는지 나눈다.
|
||||||
|
- 복수 후보일 때는 후보 우선순위를 추천한다. 요청 문장/변경 파일 직접성, 현재 diff 근거, Milestone 상태, 구현 잠금, 선후 의존성, Phase/Milestone 흐름상 위치를 함께 본다.
|
||||||
|
- 관련성이 비슷하면 `[검토중]` 후보는 리뷰/승인 요청에서 우선하고, 구현 작업 요청에서는 `[진행중]` 후보를 `[계획]` 후보보다 우선한다. 같은 상태라면 현재 변경 파일을 더 많이 설명하는 후보를 우선한다.
|
||||||
|
- 사용자가 특정 Phase, Milestone, epic-id, item-id, 파일 경로를 명시했으면 그 후보를 우선하되, 범위 제외나 잠금 결정 필요가 있으면 우선순위 근거에 같이 적는다.
|
||||||
|
- 로드맵이 있고 활성 Phase/Milestone 밖으로 보이면 `ROADMAP.md`의 Phase 흐름을 확인하고 전환 또는 신규 Phase/Milestone 필요성을 제안한다.
|
||||||
|
|
||||||
|
4. **남은 작업 분류**
|
||||||
|
- `확인됨`: 코드, 문서, 테스트, diff로 근거가 있는 남은 작업
|
||||||
|
- `추정됨`: 구조상 필요해 보이지만 추가 확인이 필요한 작업
|
||||||
|
- `확인 필요`: 현재 요청에 직접 영향을 주는 제품 판단, 범위 결정, 사용자 의도가 필요한 작업
|
||||||
|
- 완료 여부는 evidence 없이 확정하지 않는다.
|
||||||
|
|
||||||
|
5. **결과 보고**
|
||||||
|
- `agent-ops/skills/common/_templates/roadmap-position-report-template.md`를 기준으로 출력한다.
|
||||||
|
- 템플릿의 섹션 제목, 필드명, 순서를 바꾸지 않는다.
|
||||||
|
- 템플릿의 모든 필드를 채우며, 근거가 없으면 생략하지 말고 `없음`, `확인 불가`, `확인 필요` 중 하나로 명시한다.
|
||||||
|
- `판단 근거`에는 브랜치, 변경 파일, 로드맵 근거, 코드/테스트 근거를 각각 분리해 적는다.
|
||||||
|
- `후보 우선순위`에는 복수 후보일 때 1순위와 2순위를 적고, 단일 후보이면 `단일 후보`라고 적는다.
|
||||||
|
- `남은 작업`은 `확인됨`, `추정됨`, `확인 필요` 세 분류를 모두 유지한다.
|
||||||
|
- `다음 행동`에는 가장 우선해야 할 실행 또는 확인을 1~2개만 적는다.
|
||||||
|
- `읽은 주요 파일`에는 실제로 읽은 핵심 파일만 적는다.
|
||||||
|
|
||||||
|
## 실행 결과 검증
|
||||||
|
|
||||||
|
- [ ] `roadmap-position-report-template.md`를 읽고 그 섹션 순서와 필드명을 유지했는가
|
||||||
|
- [ ] 로드맵이 없는 프로젝트에서 `ROADMAP.md`, `current.md`, Phase, Milestone 문서를 읽으려 하지 않았는가
|
||||||
|
- [ ] 로드맵이 있는 프로젝트에서 `current.md`만 근거로 현재 위치를 단정하지 않았는가
|
||||||
|
- [ ] 로드맵이 있는 프로젝트에서 활성 Phase 문서의 목표와 Phase 경계를 확인했는가
|
||||||
|
- [ ] 로드맵이 있는 프로젝트에서 활성 Milestone 문서의 목표와 범위 제외 항목을 확인했는가
|
||||||
|
- [ ] 로드맵이 있는 프로젝트에서 활성 Milestone 문서의 `완료 리뷰` 섹션과 `[검토중]` 상태 여부를 확인했는가
|
||||||
|
- [ ] `agent-ops/roadmap/archive/**` 문서를 명시 요청 없이 읽지 않았는가
|
||||||
|
- [ ] 로드맵이 있는 프로젝트에서 활성 Milestone 문서의 `구현 잠금` 섹션 존재 여부, 상태, `결정 필요` 항목을 확인했는가
|
||||||
|
- [ ] 로드맵이 있는 프로젝트에서 추정 Phase/Milestone마다 문서 링크를 출력했는가
|
||||||
|
- [ ] 로드맵이 있는 프로젝트에서 Phase/Milestone 후보가 여럿이면 1순위와 2순위 추천 및 근거를 출력했는가
|
||||||
|
- [ ] 로드맵이 있는 프로젝트에서 관련 Epic/Task id가 있으면 결과에 함께 표시했는가
|
||||||
|
- [ ] 변경 파일 또는 사용자 요청과 Phase/Milestone 판단 근거가 연결되어 있는가
|
||||||
|
- [ ] 남은 작업을 `확인됨`, `추정됨`, `확인 필요`로 구분했는가
|
||||||
|
- [ ] 템플릿 필드를 근거 없이 생략하지 않고 `없음`, `확인 불가`, `확인 필요`로 채웠는가
|
||||||
|
- [ ] 로드맵 파일을 수정하지 않았는가
|
||||||
|
|
||||||
|
## 출력 형식
|
||||||
|
|
||||||
|
- 템플릿 경로: `agent-ops/skills/common/_templates/roadmap-position-report-template.md`
|
||||||
|
- 템플릿을 그대로 복사해 placeholder를 채운다.
|
||||||
|
- 섹션 제목과 필드명을 임의로 번역, 축약, 삭제하지 않는다.
|
||||||
|
- 값이 없는 필드는 `없음`, `확인 불가`, `확인 필요` 중 하나로 채운다.
|
||||||
|
- 로드맵이 없는 프로젝트에서는 추정 Phase, 추정 Milestone, Phase 링크, Milestone 링크, 로드맵 근거를 `없음`으로 채운다.
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- `current.md`만 읽고 현재 작업 위치를 확정하지 않는다.
|
||||||
|
- 로드맵이 없는 프로젝트에서 로드맵 파일을 만들거나 읽는 것을 현재 작업 분석의 선행 조건으로 삼지 않는다.
|
||||||
|
- 사용자가 명시하지 않은 상태에서 `ROADMAP.md`, `current.md`, Phase, Milestone 문서를 수정하지 않는다.
|
||||||
|
- 사용자가 명시하지 않은 상태에서 `agent-ops/roadmap/archive/**`를 읽지 않는다.
|
||||||
|
- evidence 없이 Phase, Milestone, Epic, Task를 `[완료]` 또는 `[검토중]`으로 처리하지 않는다.
|
||||||
|
- 활성 Phase/Milestone 밖 작업을 임의로 새 항목으로 추가하지 않는다.
|
||||||
353
agent-ops/skills/common/code-review/SKILL.md
Normal file
353
agent-ops/skills/common/code-review/SKILL.md
Normal file
|
|
@ -0,0 +1,353 @@
|
||||||
|
---
|
||||||
|
name: code-review
|
||||||
|
description: Use for active task review requests such as 리뷰 진행해, 리뷰해줘, 코드 리뷰해줘, code review, CODE_REVIEW.md, 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, moves the task to archive, and reports m-prefixed completion metadata for runtime; WARN/FAIL immediately writes follow-up PLAN/CODE_REVIEW files. Never stop after verdict append.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Code Review
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Review the implementation phase of the plan-code-review loop:
|
||||||
|
|
||||||
|
```text
|
||||||
|
plan skill -> implementation -> code-review skill
|
||||||
|
^ |
|
||||||
|
+----- issues found: new routed plan/review files
|
||||||
|
```
|
||||||
|
|
||||||
|
## Core Loop Rules
|
||||||
|
|
||||||
|
- Trigger: Korean or English active-task review requests, including `리뷰 진행해` and `리뷰해줘`, must use this skill when an active `CODE_REVIEW-*-G??.md` exists under `agent-task/*/` or `agent-task/*/*/`, excluding `agent-task/archive/**`.
|
||||||
|
- Finalize every selected active review: append one verdict, archive the active review and plan files, then create exactly one next state before reporting.
|
||||||
|
- 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` writes the next active `PLAN-{build_lane}-GNN.md` and `CODE_REVIEW-{review_lane}-GNN.md`.
|
||||||
|
- Do not ask for confirmation before WARN/FAIL follow-up files. If details are uncertain, write the smallest concrete follow-up plan with file references and verification commands.
|
||||||
|
- Recovery: if a prior turn appended a verdict without archive or next-state files, resume at Step 5 and finish finalization first.
|
||||||
|
|
||||||
|
## Workflow Contract
|
||||||
|
|
||||||
|
Active work must live under an active task directory using routed filenames. This is the state protocol shared with the plan skill.
|
||||||
|
|
||||||
|
Task path terms:
|
||||||
|
|
||||||
|
- `{task_group}` is the top-level work category under `agent-task/`. Normal task groups use a short snake_case name such as `refactoring`.
|
||||||
|
- Milestone-linked work uses the reserved task group form `m-<milestone-slug>`, where `<milestone-slug>` is the active Milestone filename without `.md`.
|
||||||
|
- `{subtask_dir}` is used only for split work and follows the indexed directory naming contract, such as `01_core` or `02+01_db`.
|
||||||
|
- `{subtask_name}` is the short snake_case name after the index or dependency prefix inside `{subtask_dir}`.
|
||||||
|
- `{task_name}` in headers and templates means the active task path relative to `agent-task/`: either `{task_group}` for a single-plan task or `{task_group}/{subtask_dir}` for a split subtask.
|
||||||
|
- A single-plan task stores active files directly under `agent-task/{task_group}/`.
|
||||||
|
- Split work stores active files under `agent-task/{task_group}/{subtask_dir}/`; the parent `agent-task/{task_group}/` is only the grouping folder and must not contain active plan/review files.
|
||||||
|
|
||||||
|
Filename rules:
|
||||||
|
|
||||||
|
- Plan file: `PLAN-{build_lane}-GNN.md`
|
||||||
|
- Review file: `CODE_REVIEW-{review_lane}-GNN.md`
|
||||||
|
- `{lane}` is only `local` or `cloud`; never put model names in filenames.
|
||||||
|
- `GNN` is a two-digit capability grade from `G01` to `G10`; runtime maps lane+grade to current models externally.
|
||||||
|
|
||||||
|
Multi-plan runtime contract:
|
||||||
|
|
||||||
|
- Multi-plan work is represented as multiple subtask directories under one shared `{task_group}`. Each subtask directory owns exactly one normal active plan file and one normal active review file.
|
||||||
|
- Multi-plan subtask directory names encode runtime scheduling metadata:
|
||||||
|
- `NN_{subtask_name}` has no runtime dependencies.
|
||||||
|
- `NN+PP[,QQ...]_{subtask_name}` depends on the listed earlier task indices.
|
||||||
|
- Subtask directory names are the runtime dependency source of truth. Preserve them verbatim; do not normalize, reinterpret, infer extra dependencies from numeric order, or choose execution order by agent judgment.
|
||||||
|
- If the user/runtime names a task group, task path, or subtask directory that identifies exactly one active review file, review that directory even when other active review files exist.
|
||||||
|
|
||||||
|
Milestone task group contract:
|
||||||
|
|
||||||
|
- `agent-task/m-<milestone-slug>/` is reserved for Milestone-linked work created by the plan skill.
|
||||||
|
- Do not treat normal task groups that do not start with `m-` as runtime milestone completion targets.
|
||||||
|
- For a selected task path, parse only the first path segment as `{task_group}`. If it matches `^m-[a-z0-9][a-z0-9-]*$`, strip `m-` to get `<milestone-slug>`.
|
||||||
|
- Do not read or modify `agent-ops/roadmap/**` for milestone routing during code-review finalization.
|
||||||
|
- Do not call `update-roadmap` from this skill. The runtime consumes the PASS completion event, checks current state, resolves the active Milestone, and calls `update-roadmap` if needed.
|
||||||
|
- For `m-<milestone-slug>` PASS tasks, report the original active task path, final archive path, complete log path, task group, and milestone slug so the runtime has deterministic event inputs.
|
||||||
|
|
||||||
|
Review routing rules:
|
||||||
|
|
||||||
|
- `local`: narrow, low-risk, or first-pass review where tests and scope are clear.
|
||||||
|
- `cloud`: multi-file, API/call-site impact, meaningful test judgment, plan deviation, weak verification, security/auth, storage/migration, concurrency, protocol/schema, cross-domain, or repeated Required issues.
|
||||||
|
- `cloud-G07` or higher is mandatory for terminal-agent follow-up work: shell/CLI workflow implementation, bin script orchestration, process control, stdout/stderr parsing, exit-status contracts, long-running command diagnosis, or terminal benchmark-style tasks. Merely running deterministic tests such as `go test` does not make a task terminal-agent work.
|
||||||
|
- `cloud-G07` or higher is mandatory for follow-up plans when a local implementation failed a real bin/smoke/integration command after unit tests passed, when the success condition depends on an interactive TUI/PTY/browser/external CLI or screen repaint/cursor stream, or when verification trust is Fail because recorded stdout/stderr does not match a rerun.
|
||||||
|
|
||||||
|
Directory states:
|
||||||
|
|
||||||
|
| State | Meaning |
|
||||||
|
|-------|---------|
|
||||||
|
| `PLAN-*-G??.md` + `CODE_REVIEW-*-G??.md` stub or placeholders | Implementation is pending/incomplete; review should fail completeness if invoked |
|
||||||
|
| `PLAN-*-G??.md` + filled `CODE_REVIEW-*-G??.md` | Ready for code-review skill |
|
||||||
|
| `complete.log` + `*.log` files | Task complete (PASS), before final task-directory archive move |
|
||||||
|
| `agent-task/archive/YYYY/MM/{task_name}/complete.log` + `*.log` files | Archived completed task path (PASS); not active |
|
||||||
|
| Only `*.log` files (no `complete.log`) | Task terminated mid-loop or abandoned |
|
||||||
|
|
||||||
|
The implementing agent never archives or deletes active files; archiving is this skill's responsibility.
|
||||||
|
|
||||||
|
## Step 1 - Find Active Task
|
||||||
|
|
||||||
|
Find active review files with both globs, excluding `agent-task/archive/**`:
|
||||||
|
|
||||||
|
- `agent-task/*/CODE_REVIEW-*-G??.md`
|
||||||
|
- `agent-task/*/*/CODE_REVIEW-*-G??.md`
|
||||||
|
|
||||||
|
| Result | Action |
|
||||||
|
|--------|--------|
|
||||||
|
| Exactly one | Review that task; exactly one `PLAN-*-G??.md` is expected beside it |
|
||||||
|
| None | Nothing to review; stop and report |
|
||||||
|
| Multiple | If the user/runtime named a task group, task path, or subtask directory that identifies exactly one active review file, review that directory. Otherwise list paths and ask which task to review; do not choose by agent judgment. |
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
## Step 3 - Pre-Review Checklist
|
||||||
|
|
||||||
|
Before writing the verdict:
|
||||||
|
|
||||||
|
- Compare actual source files against every planned checklist item.
|
||||||
|
- Compare the plan `구현 체크리스트` and review stub `구현 체크리스트`; item text/order must match.
|
||||||
|
- Confirm the implementation marked the matching checklist items in the active review file, including the final mandatory `CODE_REVIEW-*-G??.md` completion item.
|
||||||
|
- Treat blank placeholder sections, missing actual implementation notes, missing checklist completion, or missing actual stdout/stderr in the active review file as a completeness or verification-trust failure.
|
||||||
|
- 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`.
|
||||||
|
|
||||||
|
Required fields:
|
||||||
|
|
||||||
|
- `종합 판정`: exactly `PASS`, `WARN`, or `FAIL`.
|
||||||
|
- `차원별 평가`: Pass/Warn/Fail for correctness, completeness, test coverage, API contract, code quality, plan deviation, verification trust.
|
||||||
|
- `발견된 문제`: `없음`, or bullets using `Required`, `Suggested`, or `Nit` with `file:line` and a concrete fix.
|
||||||
|
- `다음 단계`: keep only the matching PASS/WARN/FAIL 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 |
|
||||||
|
| `FAIL` | One or more Required issues. | Yes |
|
||||||
|
|
||||||
|
Issue severity:
|
||||||
|
|
||||||
|
- `Required`: correctness, API contract, missing required test, plan-completeness issue, or incomplete/placeholder `CODE_REVIEW-*-G??.md` content required from the implementing agent.
|
||||||
|
- `Suggested`: useful improvement that should enter the loop but does not block correctness.
|
||||||
|
- `Nit`: tiny cleanup; may be recorded without forcing WARN.
|
||||||
|
|
||||||
|
Verdict consistency:
|
||||||
|
|
||||||
|
- `PASS` requires all dimensions to be Pass and no Required/Suggested issues. Nit-only findings may still PASS only when every dimension remains Pass.
|
||||||
|
- Any Fail dimension or any Required issue forces `FAIL`.
|
||||||
|
- Any Warn dimension or any Suggested issue forces `WARN`, unless the only findings are explicitly Nit and every dimension remains Pass.
|
||||||
|
|
||||||
|
## Step 5 - Archive Active Files
|
||||||
|
|
||||||
|
Archive is mandatory for `PASS`, `WARN`, and `FAIL`. Archive order is fixed:
|
||||||
|
|
||||||
|
1. Count existing `code_review_*.log` as `N`; rename `CODE_REVIEW-{review_lane}-GNN.md` to `code_review_{review_lane}_GNN_N.log`.
|
||||||
|
2. Count existing `plan_*.log` as `M`; rename `PLAN-{build_lane}-GNN.md` to `plan_{build_lane}_GNN_M.log`.
|
||||||
|
|
||||||
|
After archiving, neither active `.md` file remains unless Step 6 writes a follow-up.
|
||||||
|
|
||||||
|
## Step 6 - Post-Review Actions
|
||||||
|
|
||||||
|
For `PASS`, write `agent-task/{task_name}/complete.log` before reporting.
|
||||||
|
|
||||||
|
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`.
|
||||||
|
- 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`, write new routed plan/review files using the plan skill format:
|
||||||
|
|
||||||
|
- New plan number is the count of `plan_*.log` after archive.
|
||||||
|
- Header tag is `REVIEW_<PARENT_TAG>`.
|
||||||
|
- If the selected task group is `m-<milestone-slug>`, write the follow-up plan/review under the same `m-<milestone-slug>` task group.
|
||||||
|
- Base the follow-up scope directly on the archived review findings. Keep it narrow and actionable.
|
||||||
|
- Choose lane/grade again; preserve the prior route only when it was adequate, otherwise raise `GNN` and/or move `local -> cloud`.
|
||||||
|
- Before choosing the follow-up route, apply this escalation gate:
|
||||||
|
- If the archived plan was `local-*` and the verdict is `FAIL` for correctness, completeness, test coverage, or verification trust, move the follow-up build lane to `cloud` unless the issue is trivially deterministic and review-detectable without live environment behavior.
|
||||||
|
- If the follow-up work is terminal-agent work (shell/CLI workflow implementation, bin script orchestration, process control, stdout/stderr parsing, exit-status contracts, long-running command diagnosis, or terminal benchmark-style tasks), use `cloud-G07` or higher.
|
||||||
|
- If unit tests passed but a real bin/smoke/integration command failed, use `cloud-G07` or higher.
|
||||||
|
- If the task depends on interactive TUI/PTY/browser/external CLI behavior, screen repaint/cursor stream parsing, or live command-palette state, use `cloud-G07` or higher.
|
||||||
|
- If recorded verification output was reconstructed, stale, or mismatched on rerun, use `cloud-G07` or higher and make verification trust recovery a plan item.
|
||||||
|
- `FAIL`: one plan item per Required issue.
|
||||||
|
- `WARN`: one grouped plan item for Suggested issues, plus related Nit issues if useful.
|
||||||
|
- Each plan item needs problem, solution with before/after when non-trivial, checklist, test decision, intermediate verification.
|
||||||
|
- The follow-up plan and review stub must contain matching `구현 체크리스트` item text/order, including the final mandatory `CODE_REVIEW-*-G??.md` completion item.
|
||||||
|
|
||||||
|
Routed review stub template (fill `{…}` placeholders; everything else is fixed and must not be changed by the implementing agent):
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
<!-- task={task_name} plan={N} tag={TAG} -->
|
||||||
|
|
||||||
|
# Code Review Reference - {TAG}
|
||||||
|
|
||||||
|
> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.**
|
||||||
|
> The task is NOT complete until every implementation-owned section below is filled in.
|
||||||
|
> Complete the `구현 체크리스트`; the final checklist item is mandatory before saving.
|
||||||
|
> Fill implementation-owned sections, then stop with active files in place and report ready for review.
|
||||||
|
> Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, `코드리뷰 전용 체크리스트`) is review-agent-only, even after compaction/resume.
|
||||||
|
> Follow the ownership table at the bottom of this file for which sections you own.
|
||||||
|
|
||||||
|
## 개요
|
||||||
|
|
||||||
|
date={YYYY-MM-DD}
|
||||||
|
task={task_name}, plan={N}, tag={TAG}
|
||||||
|
|
||||||
|
## 이 파일을 읽는 리뷰 에이전트에게
|
||||||
|
|
||||||
|
> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다.
|
||||||
|
|
||||||
|
각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
|
||||||
|
리뷰 완료는 아래 순서까지 끝난 상태를 의미합니다.
|
||||||
|
|
||||||
|
1. 판정을 append한다.
|
||||||
|
2. `CODE_REVIEW-{review_lane}-GNN.md` → `code_review_{review_lane}_GNN_N.log`, `PLAN-{build_lane}-GNN.md` → `plan_{build_lane}_GNN_M.log`로 아카이브한다.
|
||||||
|
3. PASS이면 `complete.log` 작성 후 active task 디렉터리를 `agent-task/archive/YYYY/MM/{task_name}/`로 이동한다. WARN/FAIL이면 다음 active plan/review 파일을 즉시 작성한다.
|
||||||
|
4. PASS이고 task group이 `m-<milestone-slug>`이면 완료 이벤트 메타데이터를 보고한다. roadmap 상태 체크와 `update-roadmap` 호출은 런타임 책임이다.
|
||||||
|
5. 적용 가능한 `코드리뷰 전용 체크리스트` 항목을 최종 `.log` 위치에서 체크한 뒤 보고한다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 구현 항목별 완료 여부
|
||||||
|
|
||||||
|
| 항목 | 완료 여부 |
|
||||||
|
|------|---------|
|
||||||
|
| [{TAG}-1] {item description} | [ ] |
|
||||||
|
| [{TAG}-2] {item description} | [ ] |
|
||||||
|
|
||||||
|
## 구현 체크리스트
|
||||||
|
|
||||||
|
{copy the follow-up plan's 구현 체크리스트 items exactly, preserving order and checkbox text}
|
||||||
|
|
||||||
|
## 코드리뷰 전용 체크리스트
|
||||||
|
|
||||||
|
> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다.
|
||||||
|
> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다.
|
||||||
|
|
||||||
|
- [ ] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다.
|
||||||
|
- [ ] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다.
|
||||||
|
- [ ] active `CODE_REVIEW-*-G??.md`를 `code_review_{review_lane}_GNN_N.log`로 아카이브한다.
|
||||||
|
- [ ] active `PLAN-*-G??.md`를 `plan_{build_lane}_GNN_M.log`로 아카이브한다.
|
||||||
|
- [ ] 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이면 다음 active `PLAN-{build_lane}-GNN.md`와 `CODE_REVIEW-{review_lane}-GNN.md`를 작성하고 `complete.log`를 작성하지 않는다.
|
||||||
|
|
||||||
|
## 계획 대비 변경 사항
|
||||||
|
|
||||||
|
_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._
|
||||||
|
|
||||||
|
## 주요 설계 결정
|
||||||
|
|
||||||
|
_구현 에이전트가 주요 설계 결정 사항을 기록한다._
|
||||||
|
|
||||||
|
## 리뷰어를 위한 체크포인트
|
||||||
|
|
||||||
|
{pre-filled from plan — one bullet per review focus area}
|
||||||
|
|
||||||
|
## 검증 결과
|
||||||
|
|
||||||
|
_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._
|
||||||
|
|
||||||
|
필수 규칙:
|
||||||
|
- 검증 명령은 고정된 계약이다. 임의로 대체하지 않는다.
|
||||||
|
- 대체가 필요하면 `계획 대비 변경 사항`에 이유와 대체 명령을 기록한다.
|
||||||
|
- `검증 결과`에는 실제 stdout/stderr를 붙여 넣는다.
|
||||||
|
|
||||||
|
### {TAG}-1 중간 검증
|
||||||
|
```
|
||||||
|
$ {verification command from plan}
|
||||||
|
(output)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 최종 검증
|
||||||
|
```
|
||||||
|
$ {final verification command from plan}
|
||||||
|
(output)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section: completion table, implementation checklist, changes from plan, design decisions, and verification output?**
|
||||||
|
> If anything is blank, go back and fill it in before saving this file.
|
||||||
|
> Leave review-agent-only sections unchanged.
|
||||||
|
```
|
||||||
|
|
||||||
|
Sections and their ownership:
|
||||||
|
|
||||||
|
| 섹션 | 소유자 | 설명 |
|
||||||
|
|------|--------|------|
|
||||||
|
| 헤더 주석, 개요(date/task/plan/tag), 리뷰 에이전트 지시 | 스텁 생성 시 고정 | 구현 에이전트가 수정하거나 실행하지 않음 |
|
||||||
|
| 구현 항목별 완료 여부 (항목명) | 스텁 생성 시 고정 | `[ ]` → `[x]` 체크만 구현 에이전트가 수행 |
|
||||||
|
| 구현 체크리스트 (항목 텍스트/순서) | follow-up plan에서 복사해 스텁 생성 시 고정 | 구현 에이전트가 `[ ]` → `[x]` 체크만 수행; 마지막 체크박스는 저장 전 필수 |
|
||||||
|
| 코드리뷰 전용 체크리스트 | Review agent only | Implementing agent must not modify or check this section |
|
||||||
|
| 계획 대비 변경 사항, 주요 설계 결정 | 구현 에이전트가 채움 | placeholder 텍스트를 실제 내용으로 교체 |
|
||||||
|
| 리뷰어를 위한 체크포인트 | 스텁 생성 시 고정 | 계획에서 추출한 리뷰 포인트 |
|
||||||
|
| 검증 결과 (섹션 제목 + 명령) | 스텁 생성 시 고정 | 실행 출력만 구현 에이전트가 채움; 명령 변경은 `계획 대비 변경 사항`에 기록 |
|
||||||
|
| 코드리뷰 결과 | 리뷰 에이전트가 append | 스텁에 포함하지 않음 |
|
||||||
|
|
||||||
|
## Step 7 - Complete Review-Only Checklist, Move PASS Task, And Report
|
||||||
|
|
||||||
|
After Step 6:
|
||||||
|
|
||||||
|
- If verdict is `PASS`, determine archive month from the current completion date as `YYYY/MM`, create the needed archive parent directories, then move the selected active task directory `agent-task/{task_name}/` to `agent-task/archive/YYYY/MM/{task_name}/`. For split work, the selected active task directory is the subtask directory, and the archive must preserve the task group path, e.g. `agent-task/refactoring/01_core/` moves to `agent-task/archive/YYYY/MM/refactoring/01_core/`.
|
||||||
|
- Do not overwrite an existing archive directory. If `agent-task/archive/YYYY/MM/{task_name}/` already exists, append the next numeric suffix to the final path segment: single-plan `agent-task/archive/YYYY/MM/{task_group}_1/`, split-plan `agent-task/archive/YYYY/MM/{task_group}/{subtask_dir}_1/`, and so on.
|
||||||
|
- After moving a split subtask, remove the active parent `agent-task/{task_group}/` only if it is empty. If sibling subtask directories or other files remain, leave the parent task group in place.
|
||||||
|
- If verdict is `PASS` and `{task_group}` matches `m-<milestone-slug>`, do not resolve the roadmap target and do not call `update-roadmap`. Report completion event metadata after the task archive move: `origin-task=agent-task/{task_name}` from the original active task path, `task-group={task_group}`, `milestone-slug=<milestone-slug>`, final archive path, `complete.log` path, and archived plan/review log paths.
|
||||||
|
- The runtime consumes that completion event, checks current state, resolves `agent-ops/roadmap/phase/*/milestones/<milestone-slug>.md`, and calls `update-roadmap` if needed.
|
||||||
|
- `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.
|
||||||
|
- For `PASS`, open the moved `agent-task/archive/YYYY/MM/{final_task_name}/code_review_{review_lane}_GNN_N.log`, where `{final_task_name}` is the archived task path, including `{task_group}/` for split work.
|
||||||
|
- For `WARN` or `FAIL`, open `agent-task/{task_name}/code_review_{review_lane}_GNN_N.log`.
|
||||||
|
- 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, or follow-up plan/review 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` the final task archive move, and for `m-*` PASS tasks the completion event metadata.
|
||||||
|
|
||||||
|
Report Required/Suggested counts, archive names, the final task archive path for `PASS` or new plan path for `WARN`/`FAIL`, and any `m-*` runtime completion event metadata.
|
||||||
|
|
||||||
|
## Review Dimensions
|
||||||
|
|
||||||
|
| Dimension | Check |
|
||||||
|
|-----------|-------|
|
||||||
|
| Correctness | Logic, edge cases, concurrency, errors |
|
||||||
|
| Completeness | All planned checklist items done, including matching plan/review `구현 체크리스트` completion |
|
||||||
|
| Test coverage | Required tests present and meaningful |
|
||||||
|
| API contract | Call sites, compatibility, docs |
|
||||||
|
| Code quality | No debug prints, dead code, leftover TODOs |
|
||||||
|
| Plan deviation | Deviations justified, no unrelated risk |
|
||||||
|
| Verification trust | Reported output matches actual code |
|
||||||
|
|
||||||
|
## Quality Rules
|
||||||
|
|
||||||
|
- Lead with findings; use specific `file:line`.
|
||||||
|
- Provide a concrete fix for every Required issue.
|
||||||
|
- Name exact stale symbols or missing tests.
|
||||||
|
- Do not write vague praise or style opinions without a rule.
|
||||||
|
- Every dimension gets Pass/Warn/Fail.
|
||||||
|
- For follow-up plans about verification trust, specify deterministic commands, for example `rg --sort path`, and forbid repo-local tool artifacts.
|
||||||
|
|
||||||
|
## Final Checklist
|
||||||
|
|
||||||
|
- `code_review_{review_lane}_GNN_N.log` exists with verdict appended.
|
||||||
|
- `plan_{build_lane}_GNN_M.log` exists.
|
||||||
|
- No active `.md` files remain after PASS.
|
||||||
|
- 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 split: empty active parent `agent-task/{task_group}/` removed after the subtask move; non-empty parent left in place.
|
||||||
|
- WARN/FAIL: new active `PLAN-{build_lane}-GNN.md` and `CODE_REVIEW-{review_lane}-GNN.md` created with matching headers and matching `구현 체크리스트`; no `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 continue task loops"
|
||||||
|
default_prompt: "Use $code-review to review the active repository task, archive active files, and create complete.log or follow-up plan/review files."
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
# Complete - {task_name}
|
||||||
|
|
||||||
|
## 완료 일시
|
||||||
|
|
||||||
|
{YYYY-MM-DD or ISO-8601}
|
||||||
|
|
||||||
|
## 요약
|
||||||
|
|
||||||
|
{one-line task summary, loop count, and final verdict}
|
||||||
|
|
||||||
|
## 루프 이력
|
||||||
|
|
||||||
|
| 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} |
|
||||||
|
|
||||||
|
## 구현/정리 내용
|
||||||
|
|
||||||
|
- {implemented or cleaned-up change}
|
||||||
|
|
||||||
|
## 최종 검증
|
||||||
|
|
||||||
|
- `{command}` - {PASS/FAIL/BLOCKED}; {actual output summary or saved output path}
|
||||||
|
|
||||||
|
## 잔여 Nit
|
||||||
|
|
||||||
|
- 없음
|
||||||
|
|
||||||
|
## 후속 작업
|
||||||
|
|
||||||
|
- 없음
|
||||||
124
agent-ops/skills/common/commit-push/SKILL.md
Normal file
124
agent-ops/skills/common/commit-push/SKILL.md
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
---
|
||||||
|
name: commit-push
|
||||||
|
version: 1.0.0
|
||||||
|
description: 변경 사항을 커밋하고 원격에 푸시한다. "커밋해줘", "푸시해줘", "커밋하고 푸시" 요청 시 사용한다.
|
||||||
|
---
|
||||||
|
|
||||||
|
# commit-push
|
||||||
|
|
||||||
|
## 목적
|
||||||
|
|
||||||
|
현재 변경 내용을 분석하여 한국어 커밋 메시지를 작성하고, 커밋 및 푸시를 수행한다.
|
||||||
|
|
||||||
|
## 언제 호출할지
|
||||||
|
|
||||||
|
- "커밋해줘", "커밋하고 푸시해줘" 요청 시
|
||||||
|
- "변경 사항 올려줘", "푸시해줘" 요청 시
|
||||||
|
- 코드 작업 완료 후 "반영해줘", "올려줘" 요청 시
|
||||||
|
|
||||||
|
## 입력
|
||||||
|
|
||||||
|
- `scope`: 커밋 범위 — all(전체) 또는 특정 파일/경로 (선택, 기본값: all)
|
||||||
|
- `push`: 푸시 여부 (선택, 기본값: true)
|
||||||
|
|
||||||
|
## 먼저 확인할 것
|
||||||
|
|
||||||
|
- [ ] 커밋할 변경 사항이 존재하는가 (`git status`로 확인)
|
||||||
|
- [ ] 현재 브랜치가 올바른 브랜치인가
|
||||||
|
- [ ] `.env`, 시크릿 파일 등 민감한 파일이 스테이징에 포함되어 있지 않은가
|
||||||
|
|
||||||
|
## 실행 절차
|
||||||
|
|
||||||
|
1. **변경 사항 파악**
|
||||||
|
- `git status`로 변경/추가/삭제된 파일 목록을 확인한다
|
||||||
|
- `git diff`로 구체적인 변경 내용을 확인한다
|
||||||
|
- 변경 사항이 없으면 사용자에게 알리고 종료한다
|
||||||
|
|
||||||
|
2. **민감 파일 검사**
|
||||||
|
- 스테이징 대상에 아래 패턴이 포함되면 해당 파일을 제외하고 사용자에게 경고한다
|
||||||
|
- `.env`, `.env.*`
|
||||||
|
- `*secret*`, `*credential*`, `*password*`
|
||||||
|
- `*.pem`, `*.key`, `*.p12`
|
||||||
|
- `.gitignore`에 이미 등록된 파일은 무시한다
|
||||||
|
|
||||||
|
3. **커밋 메시지 작성**
|
||||||
|
- 변경 내용을 분석하여 한국어로 커밋 메시지를 작성한다
|
||||||
|
- 아래 메시지 규칙을 따른다
|
||||||
|
|
||||||
|
4. **사용자 확인**
|
||||||
|
- 커밋 메시지와 대상 파일 목록을 보여주고 승인을 받는다
|
||||||
|
- 사용자가 메시지 수정을 요청하면 반영한다
|
||||||
|
|
||||||
|
5. **커밋 실행**
|
||||||
|
- scope에 따라 파일을 스테이징한다
|
||||||
|
- all: 변경된 전체 파일을 개별적으로 `git add`
|
||||||
|
- 특정 경로: 해당 파일만 `git add`
|
||||||
|
- 승인된 메시지로 `git commit`을 실행한다
|
||||||
|
|
||||||
|
6. **푸시 실행**
|
||||||
|
- push가 true인 경우에만 실행한다
|
||||||
|
- 현재 브랜치를 원격에 푸시한다
|
||||||
|
- 원격 브랜치가 없으면 `-u origin {branch}`로 설정한다
|
||||||
|
- 충돌 발생 시 사용자에게 알리고 중단한다
|
||||||
|
|
||||||
|
7. **결과 보고**
|
||||||
|
- 커밋 해시, 메시지, 변경 파일 수, 푸시 결과를 출력한다
|
||||||
|
|
||||||
|
## 커밋 메시지 규칙
|
||||||
|
|
||||||
|
### 형식
|
||||||
|
|
||||||
|
```
|
||||||
|
<타입>: <변경 요약>
|
||||||
|
|
||||||
|
<본문> (선택)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 타입 목록
|
||||||
|
|
||||||
|
| 타입 | 용도 |
|
||||||
|
|------|------|
|
||||||
|
| 기능 | 새로운 기능 추가 |
|
||||||
|
| 수정 | 버그 수정 |
|
||||||
|
| 개선 | 기존 기능 개선, 리팩토링 |
|
||||||
|
| 문서 | 문서 추가/수정 |
|
||||||
|
| 설정 | 빌드, CI/CD, 설정 파일 변경 |
|
||||||
|
| 테스트 | 테스트 추가/수정 |
|
||||||
|
| 정리 | 코드 정리, 불필요 코드 제거 |
|
||||||
|
|
||||||
|
### 작성 원칙
|
||||||
|
|
||||||
|
- **한국어**로 작성한다
|
||||||
|
- 요약은 50자 이내로 간결하게 작성한다
|
||||||
|
- 요약은 "~한다" 형태의 서술형으로 끝낸다 (예: "로그인 검증 로직을 추가한다")
|
||||||
|
- 본문은 **무엇을** 변경했는지가 아니라 **왜** 변경했는지를 쓴다
|
||||||
|
- 변경 파일이 3개 이하이면 본문을 생략할 수 있다
|
||||||
|
- 여러 성격의 변경이 섞여 있으면 가장 핵심적인 변경을 기준으로 타입을 정한다
|
||||||
|
|
||||||
|
## 출력 형식
|
||||||
|
|
||||||
|
```
|
||||||
|
## 커밋 완료
|
||||||
|
|
||||||
|
- 브랜치: {브랜치명}
|
||||||
|
- 커밋: {해시} — {커밋 메시지 요약}
|
||||||
|
- 변경 파일: {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`를 사용하지 않는다
|
||||||
|
- 사용자 확인 없이 커밋하지 않는다
|
||||||
|
- 영어로 커밋 메시지를 작성하지 않는다
|
||||||
|
- 변경 내용과 무관한 커밋 메시지를 작성하지 않는다
|
||||||
|
- `--no-verify` 옵션을 사용하지 않는다
|
||||||
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 파일 생성만 담당한다
|
||||||
153
agent-ops/skills/common/create-readme/SKILL.md
Normal file
153
agent-ops/skills/common/create-readme/SKILL.md
Normal file
|
|
@ -0,0 +1,153 @@
|
||||||
|
---
|
||||||
|
name: create-readme
|
||||||
|
version: 1.0.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-ops/roadmap/current.md`가 있으면 README에 현재 작업 위치를 복사하지 말고, 로드맵을 확인할 문서 경로만 적는다.
|
||||||
|
- README는 제품 소개 문서이면서 작업 진입점이다. 마케팅 문구보다 실행 가능한 정보와 프로젝트 경계를 우선한다.
|
||||||
|
- 불확실한 내용은 단정하지 않고 `TODO` 또는 "확인 필요"로 남긴다.
|
||||||
|
|
||||||
|
## 먼저 확인할 것
|
||||||
|
|
||||||
|
- [ ] 루트 `README.md` 존재 여부와 기존 내용 확인
|
||||||
|
- [ ] `package.json`, `pyproject.toml`, `Cargo.toml`, `go.mod`, `Makefile`, `docker-compose.yml` 등 실행/검증 명령 근거 확인
|
||||||
|
- [ ] `agent-ops/rules/project/rules.md`가 있으면 프로젝트 개요, 기술 스택, 도메인 매핑 확인
|
||||||
|
- [ ] `agent-ops/roadmap/ROADMAP.md` 또는 `agent-ops/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에 길게 복사하지 않는다.
|
||||||
168
agent-ops/skills/common/create-roadmap/SKILL.md
Normal file
168
agent-ops/skills/common/create-roadmap/SKILL.md
Normal file
|
|
@ -0,0 +1,168 @@
|
||||||
|
---
|
||||||
|
name: create-roadmap
|
||||||
|
version: 1.12.0
|
||||||
|
description: AI-first 개인/소규모 프로젝트의 전체 목표, Phase scaffold, Phase 하위 Milestone 문서, current.md 활성 Phase/Milestone 창, archive Phase scaffold를 처음 생성하는 공통 스킬
|
||||||
|
---
|
||||||
|
|
||||||
|
# 로드맵 생성
|
||||||
|
|
||||||
|
## 목적
|
||||||
|
|
||||||
|
`agent-ops/roadmap/` 하위에 `Roadmap -> Phase -> Milestone` 기반 한국어 로드맵 구조를 처음 생성한다.
|
||||||
|
전체 로드맵은 전체 방향과 Phase index만 담당하고, 일반 작업에서는 `current.md`의 활성 Phase/Milestone 링크와 관련 문서만 읽도록 만든다.
|
||||||
|
Milestone은 구현 계획이 아니라 방향성, 범위, 위험, 확인 필요 사항을 기록하는 협업 문서다.
|
||||||
|
Epic과 Task는 별도 파일로 분리하지 않고 Milestone 문서의 `필수 기능` 안에서 관리한다.
|
||||||
|
|
||||||
|
## 언제 호출할지
|
||||||
|
|
||||||
|
- 프로젝트에 파일 기반 로드맵을 처음 만들 때
|
||||||
|
- 사용자가 "로드맵 만들어줘", "마일스톤 설계해줘", "goal/phase 구조 잡아줘"라고 요청할 때
|
||||||
|
- 기존 README나 메모에 흩어진 계획을 `agent-ops/roadmap/` 구조로 분리할 때
|
||||||
|
|
||||||
|
## 입력
|
||||||
|
|
||||||
|
- `overall-goal`: 프로젝트 전체 목표 한 줄 또는 짧은 문단 (선택, 없으면 README와 현재 구조에서 추론)
|
||||||
|
- `phase-hints`: 예상 Phase 목록 또는 단계 힌트 (선택)
|
||||||
|
- `milestone-hints`: 예상 Milestone 목록 또는 기능 힌트 (선택)
|
||||||
|
- `active-phases`: 현재 열어둘 Phase 목록 (선택, 없으면 현재 구현 상태와 요청에서 추론)
|
||||||
|
- `active-milestones`: 현재 열어둘 Milestone 목록 (선택, 없으면 현재 구현 상태와 요청에서 추론)
|
||||||
|
|
||||||
|
## 생성 구조
|
||||||
|
|
||||||
|
```text
|
||||||
|
agent-ops/
|
||||||
|
roadmap/
|
||||||
|
ROADMAP.md
|
||||||
|
current.md
|
||||||
|
phase/
|
||||||
|
<phase-slug>/
|
||||||
|
PHASE.md
|
||||||
|
milestones/
|
||||||
|
<milestone-slug>.md
|
||||||
|
archive/
|
||||||
|
phase/
|
||||||
|
<phase-slug>/
|
||||||
|
PHASE.md
|
||||||
|
milestones/
|
||||||
|
<milestone-slug>.md
|
||||||
|
```
|
||||||
|
|
||||||
|
| 파일 | 역할 |
|
||||||
|
|------|------|
|
||||||
|
| `agent-ops/roadmap/ROADMAP.md` | 전체 목표와 Phase 흐름만 담는 최상위 지도. 로드맵 생성/갱신/Phase 전환 때만 읽는다 |
|
||||||
|
| `agent-ops/roadmap/current.md` | 활성 Phase와 활성 Milestone 후보, 선택 규칙을 담는 얇은 포인터 |
|
||||||
|
| `agent-ops/roadmap/phase/<phase-slug>/PHASE.md` | Phase 목표, 상태, Milestone 흐름, Phase 경계를 담는 문서 |
|
||||||
|
| `agent-ops/roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md` | 일반 작업 시 읽는 Milestone 단위 목표, 구현 잠금, 범위, Epic/Task 체크리스트, 완료 기준, 범위 제외 항목 |
|
||||||
|
| `agent-ops/roadmap/archive/phase/<phase-slug>/...` | 완료 또는 폐기되어 현재 후보에서 제외한 과거 Phase/Milestone. 일반 작업에서는 읽지 않는다 |
|
||||||
|
|
||||||
|
## 템플릿
|
||||||
|
|
||||||
|
- `ROADMAP.md`는 `agent-ops/skills/common/_templates/roadmap-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` 형식을 따른다.
|
||||||
|
- `ROADMAP.md`에는 Milestone 상세 체크리스트를 넣지 않는다.
|
||||||
|
- `current.md`는 활성 Phase/Milestone 후보만 담고, 개인별 현재 작업 위치나 완료 상태를 적지 않는다.
|
||||||
|
- archive 경로는 `current.md`의 활성 항목에 넣지 않는다.
|
||||||
|
|
||||||
|
## 작성 규칙
|
||||||
|
|
||||||
|
- 기본 작성 언어는 한국어다.
|
||||||
|
- 상태 표기는 `[계획]`, `[진행중]`, `[검토중]`, `[완료]`, `[보류]`, `[폐기]` 중 하나만 사용한다.
|
||||||
|
- Phase와 Milestone 이름, 파일명에는 `1`, `2`, `M01`, `P1` 같은 순번을 붙이지 않는다.
|
||||||
|
- 진행 순서는 `ROADMAP.md`와 각 `PHASE.md`의 위에서 아래 순서로 표현한다.
|
||||||
|
- Phase 파일명은 `agent-ops/roadmap/phase/<phase-slug>/PHASE.md`로 만든다.
|
||||||
|
- Milestone 파일명은 `agent-ops/roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md`로 만든다.
|
||||||
|
- `<phase-slug>`와 `<milestone-slug>`는 소문자 영문, 숫자, 하이픈만 사용하고, 공백/언더스코어/순번 prefix를 넣지 않는다.
|
||||||
|
- 중간에 Phase나 Milestone을 끼워 넣을 수 있도록 기존 항목의 이름과 파일명을 불필요하게 바꾸지 않는다.
|
||||||
|
|
||||||
|
## Milestone 작성 규칙
|
||||||
|
|
||||||
|
- Milestone 표준 섹션은 `위치`, `목표`, `상태`, `구현 잠금`, `범위`, `필수 기능`, `완료 기준`, `완료 리뷰`, `범위 제외`, `작업 컨텍스트`다.
|
||||||
|
- 새 Milestone은 사용자만 결정할 수 있는 제품 방향, 범위, 우선순위, 책임 경계가 남아 있으면 `구현 잠금`을 `잠금`으로 둔다.
|
||||||
|
- Milestone 전체에서 사용자만 결정할 항목이 더 이상 없고 에이전트가 표준선에 따라 실행하면 되는 상태라면 `해제`로 둔다.
|
||||||
|
- `구현 잠금`에는 상태와 `결정 필요` 체크리스트만 적는다. 결정할 항목이 없으면 `결정 필요: 없음`으로 적는다.
|
||||||
|
- `필수 기능`은 Epic heading과 Task 체크리스트로 작성한다.
|
||||||
|
- Epic heading은 `### Epic: [epic-id] <이름>` 형식으로 작성한다.
|
||||||
|
- Task는 `- [ ] [item-id] 설명` 형식으로 작성한다.
|
||||||
|
- epic-id와 item-id는 공백 없는 짧은 ASCII 토큰이며, 해당 Milestone 안에서만 유일하면 된다.
|
||||||
|
- `완료 기준`은 검증 가능한 조건의 체크리스트로 작성한다.
|
||||||
|
- `완료 리뷰`는 새 Milestone에서는 `상태: 없음`, `요청일: 없음`으로 두고, 모든 필수 Task와 완료 기준이 충족된 뒤 사용자 최종 확인을 요청할 때 갱신한다.
|
||||||
|
- `범위`, `범위 제외`, `작업 컨텍스트`는 설명 목록으로 작성하고, 실행해야 할 작업을 이 섹션에 숨기지 않는다.
|
||||||
|
|
||||||
|
## 먼저 확인할 것
|
||||||
|
|
||||||
|
- [ ] `agent-ops/roadmap/ROADMAP.md` 또는 `agent-ops/roadmap/current.md`가 이미 존재하는지 확인
|
||||||
|
- [ ] 이미 존재하면 덮어쓰지 말고 `update-roadmap` 스킬 사용을 안내
|
||||||
|
- [ ] `README.md`, `agent-ops/GUIDE.md`, `agent-ops/rules/project/rules.md` 등 프로젝트 방향을 설명하는 문서를 확인
|
||||||
|
- [ ] `rg --files`로 현재 프로젝트의 주요 구조를 가볍게 확인
|
||||||
|
- [ ] `roadmap-template.md`, `roadmap-current-template.md`, `roadmap-phase-template.md`, `roadmap-milestone-template.md`를 읽어 최신 형식 확인
|
||||||
|
- [ ] `agent-ops/rules/common/rules.md`가 로드맵 디렉터리 존재 시 `agent-ops/rules/common/rules-roadmap.md`를 읽도록 라우팅하는지 확인
|
||||||
|
|
||||||
|
## 실행 절차
|
||||||
|
|
||||||
|
1. **기존 로드맵 확인**
|
||||||
|
- `agent-ops/roadmap/` 하위 기존 파일 존재 여부를 확인한다.
|
||||||
|
- 기존 로드맵이 있으면 새로 만들지 않고 `update-roadmap`을 사용하도록 안내한다.
|
||||||
|
|
||||||
|
2. **프로젝트 방향 분석**
|
||||||
|
- README와 프로젝트 규칙에서 대상 사용자, 해결하려는 문제, 현재 구현 상태를 파악한다.
|
||||||
|
- 전체 코드를 정독하지 않는다. 로드맵 설계에 필요한 문서와 상위 구조만 확인한다.
|
||||||
|
- 불확실한 제품 방향은 단정하지 않고 "가정" 또는 `<!-- TODO: 확인 필요 -->`로 남긴다.
|
||||||
|
|
||||||
|
3. **목표 / Phase / Milestone 설계**
|
||||||
|
- 전체 목표는 프로젝트가 궁극적으로 만들려는 결과를 1~3문장으로 작성한다.
|
||||||
|
- Phase는 큰 진화 단위로 나누고, 각 Phase에 목표와 상태를 둔다.
|
||||||
|
- Milestone은 Phase 안에서 완료 판단이 가능한 단위로 나눈다.
|
||||||
|
- Milestone 내부에서 하위 작업 묶음이 필요하면 Epic으로 선언하고, Epic 아래 Task 체크리스트를 둔다.
|
||||||
|
|
||||||
|
4. **파일 생성**
|
||||||
|
- `ROADMAP.md`, `current.md`, 각 Phase의 `PHASE.md`, 각 Milestone 문서를 템플릿 순서대로 생성한다.
|
||||||
|
- 활성 Phase와 활성 Milestone은 `current.md`에 모두 기록한다.
|
||||||
|
- `ROADMAP.md`의 Phase 흐름에는 완료/검토중/진행중/계획 Phase 모두를 위에서 아래 순서로 두고, 계획 Phase는 진행중 Phase보다 아래에 둔다.
|
||||||
|
- 완료된 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/`만 둘 수 있다.
|
||||||
|
|
||||||
|
5. **검증**
|
||||||
|
- 생성한 링크가 실제 파일을 가리키는지 확인한다.
|
||||||
|
- `current.md` 활성 항목에 `agent-ops/roadmap/archive/**` 경로가 없는지 확인한다.
|
||||||
|
- Epic heading과 Task 체크리스트 id가 형식을 따르는지 확인한다.
|
||||||
|
- 상태 표기가 `[진행중]`처럼 공백 없는 표준값인지 확인한다.
|
||||||
|
- Milestone 문서에 `완료 리뷰` 섹션이 있는지 확인한다.
|
||||||
|
|
||||||
|
## 출력 형식
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## 생성 완료
|
||||||
|
|
||||||
|
- 로드맵: agent-ops/roadmap/ROADMAP.md
|
||||||
|
- 현재 컨텍스트: agent-ops/roadmap/current.md
|
||||||
|
- Phase 문서: <N개>
|
||||||
|
- Milestone 문서: <N개>
|
||||||
|
- 활성 Phase: <N개>
|
||||||
|
- 활성 Milestone: <N개>
|
||||||
|
- 구현 잠금: <잠금 Milestone N개 | 해제 Milestone N개>
|
||||||
|
- 공통 로드맵 룰: <확인함 | 설치 필요 | 해당 없음>
|
||||||
|
|
||||||
|
## 활성 항목
|
||||||
|
|
||||||
|
- Phase: <phase-name>: agent-ops/roadmap/phase/<phase-slug>/PHASE.md
|
||||||
|
- Milestone: <milestone-name>: agent-ops/roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md
|
||||||
|
|
||||||
|
## TODO 항목
|
||||||
|
|
||||||
|
- <확인이 필요한 가정 또는 미정 항목> (해당 시)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- 기존 `agent-ops/roadmap/` 파일을 덮어쓰지 않는다.
|
||||||
|
- 일반 작업마다 전체 `ROADMAP.md`를 읽도록 규칙을 만들지 않는다.
|
||||||
|
- `current.md`에 `agent-ops/roadmap/archive/**` 경로를 넣지 않는다.
|
||||||
|
- 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 에 여러 독립적인 책임을 묶지 않는다
|
||||||
254
agent-ops/skills/common/init-agent-ops/SKILL.md
Normal file
254
agent-ops/skills/common/init-agent-ops/SKILL.md
Normal file
|
|
@ -0,0 +1,254 @@
|
||||||
|
---
|
||||||
|
name: init-agent-ops
|
||||||
|
version: 1.1.3
|
||||||
|
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. 초기 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` 등)이 있는지 확인
|
||||||
|
|
||||||
|
## 핵심 원칙
|
||||||
|
|
||||||
|
- 기존 구조를 우선한다.
|
||||||
|
- 새 파일 생성은 꼭 필요한 최소 범위로 제한한다.
|
||||||
|
- 도메인은 발명하지 말고 현재 구조에서 발견한다.
|
||||||
|
- 처음에는 핵심 도메인만 생성한다.
|
||||||
|
- 반복되는 작업만 초기 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 추적 제외 |
|
||||||
|
| `.geminiignore`, `.aiexclude`, `.cursorignore`, `.clineignore` | 사용자 항목은 보존하고 Agent-Ops 관리 block에 `agent-task/archive/**`, `agent-ops/roadmap/archive/**` 추가 |
|
||||||
|
| `.claude/settings.json`, `opencode.json` | 파일이 없으면 `agent-task/archive/**` 읽기/검색 제외 설정만 생성한다. `agent-ops/roadmap/archive/**`는 필요 시 링크로 읽을 수 있어야 하므로 hard read deny로 추가하지 않는다 |
|
||||||
|
|
||||||
|
에이전트별 파일명:
|
||||||
|
|
||||||
|
실제 생성/동기화 대상 목록은 `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 스캐폴드를 생성한다.
|
||||||
|
|
||||||
|
```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-ops/roadmap/archive/**`를 넣는다
|
||||||
|
- `.claude/settings.json`, `opencode.json`이 없으면 `agent-task/archive/**` 읽기/검색 제외 설정을 생성하고, 있으면 가능한 경우 기존 설정을 보존하며 필요한 제외 설정만 병합한다
|
||||||
|
- `agent-ops/roadmap/archive/**`는 일반 작업에서 읽지 않도록 AI ignore와 로드맵 규칙으로 제한하되, `.claude/settings.json`이나 `opencode.json`의 hard read deny에는 추가하지 않는다
|
||||||
|
- 기존 `.claude/settings.json`이나 `opencode.json`에 `agent-ops/roadmap/archive/**` hard read/glob deny가 있으면 사용자 설정으로 보고 자동 삭제하지 않고 경고만 남긴다
|
||||||
|
- 대상 루트에 `.agent-ops-source`가 있으면 AI ignore / permission 파일은 보강하지 않는다
|
||||||
|
- `agent-task/archive/**`와 `agent-ops/roadmap/archive/**` 제외는 `.gitignore`에 추가하지 않는다
|
||||||
|
|
||||||
|
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. **초기 skill 제안**
|
||||||
|
- 신규 프로젝트: 최소 2개만 제안한다
|
||||||
|
- 운영중 프로젝트: 반복 작업 기반으로 필요한 skill을 제안한다
|
||||||
|
|
||||||
|
8. **결과 보고**
|
||||||
|
- 상태 판별 결과, 생성된 파일 목록, 도메인 제안, 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/` 항목이 추가되어 있는가
|
||||||
|
- [ ] `.geminiignore`, `.aiexclude`, `.cursorignore`, `.clineignore`에 Agent-Ops 관리 block이 있고 그 안에 `agent-task/archive/**`와 `agent-ops/roadmap/archive/**`가 포함되어 있는가
|
||||||
|
- [ ] `.claude/settings.json`, `opencode.json`에 `agent-task/archive/**` 제외 설정이 있거나, 병합 불가 시 수동 병합 안내를 출력했는가
|
||||||
|
- [ ] `.claude/settings.json`, `opencode.json`에 `agent-ops/roadmap/archive/**` hard read deny를 새로 추가하지 않았는가
|
||||||
|
- [ ] 기존 `agent-ops/roadmap/archive/**` hard deny가 있으면 자동 삭제하지 않고 사용자 확인 대상으로 보고했는가
|
||||||
|
- [ ] `.gitignore`에 `agent-task/archive/**` 또는 `agent-ops/roadmap/archive/**`를 추가하지 않았는가
|
||||||
|
- 검증 실패 시: 누락된 파일/항목을 사용자에게 알리고 해당 부분만 보완한다
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- 진입 파일에 rules/common/rules.md 외 내용을 추가하지 않는다.
|
||||||
|
- `agent-task/archive/**`와 `agent-ops/roadmap/archive/**` 제외를 `.gitignore`에 추가하지 않는다.
|
||||||
|
- 실제 구조보다 앞선 추상 구조를 강요하지 않는다.
|
||||||
|
- 처음부터 많은 domain / skill을 만들지 않는다.
|
||||||
|
- rules/common/rules.md를 프로젝트에서 직접 수정하지 않는다.
|
||||||
|
- rules/project/rules.md에 rules/common/rules.md와 중복되는 내용을 넣지 않는다.
|
||||||
384
agent-ops/skills/common/plan/SKILL.md
Normal file
384
agent-ops/skills/common/plan/SKILL.md
Normal file
|
|
@ -0,0 +1,384 @@
|
||||||
|
---
|
||||||
|
name: plan
|
||||||
|
description: Analyze the current repository and write a detailed PLAN-{build_lane}-GNN.md for implementation work. Also writes the CODE_REVIEW-{review_lane}-GNN.md stub that the implementing agent will fill in after coding. Use for any feature, refactor, bug fix, or follow-up fix that should enter the plan-code-review loop. Milestone-linked work uses a reserved m-prefixed task group so runtime can route PASS completion events to update-roadmap. A separate implementing agent, or the same agent in an implementation pass, reads the plan file and does the coding.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Plan
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Create the planning artifacts for the implementation loop:
|
||||||
|
|
||||||
|
```text
|
||||||
|
plan skill -> PLAN-{build_lane}-GNN.md + CODE_REVIEW-{review_lane}-GNN.md stub
|
||||||
|
implementation -> code changes + filled CODE_REVIEW-{review_lane}-GNN.md
|
||||||
|
code-review skill -> verdict + archive, complete.log, and PASS task-directory archive move or new follow-up plan/review files
|
||||||
|
runtime -> for m-prefixed PASS completion events, state check and optional update-roadmap call
|
||||||
|
```
|
||||||
|
|
||||||
|
## Workflow Contract
|
||||||
|
|
||||||
|
This skill intentionally uses routed active files under an active task directory as the state protocol. Do not change this directory or filename contract unless the paired code-review skill is updated together.
|
||||||
|
|
||||||
|
Task path terms:
|
||||||
|
|
||||||
|
- `{task_group}` is the top-level work category under `agent-task/`. Normal task groups use a short snake_case name such as `refactoring`.
|
||||||
|
- Milestone-linked work uses the reserved task group form `m-<milestone-slug>`, where `<milestone-slug>` is the active Milestone filename without `.md`.
|
||||||
|
- `{subtask_dir}` is used only for split work and follows the existing indexed directory naming rules below, such as `01_core` or `02+01_db`.
|
||||||
|
- `{subtask_name}` is the short snake_case name after the index or dependency prefix inside `{subtask_dir}`.
|
||||||
|
- `{task_name}` in headers and templates means the active task path relative to `agent-task/`: either `{task_group}` for a single-plan task or `{task_group}/{subtask_dir}` for a split subtask.
|
||||||
|
- A single-plan task stores active files directly under `agent-task/{task_group}/`.
|
||||||
|
- Split work stores active files under `agent-task/{task_group}/{subtask_dir}/`; the parent `agent-task/{task_group}/` is only the grouping folder and must not contain active plan/review files.
|
||||||
|
|
||||||
|
Filename rules:
|
||||||
|
|
||||||
|
- Plan file: `PLAN-{build_lane}-GNN.md`
|
||||||
|
- Review stub: `CODE_REVIEW-{review_lane}-GNN.md`
|
||||||
|
- `{lane}` is only `local` or `cloud`; never put model names in filenames.
|
||||||
|
- `GNN` is a two-digit capability grade from `G01` to `G10`; the runtime maps lane+grade to current models externally.
|
||||||
|
|
||||||
|
Role boundary rules:
|
||||||
|
|
||||||
|
- Implementing agents fill implementation-owned `CODE_REVIEW-*-G??.md` sections, keep active files in place, and report ready for review.
|
||||||
|
- 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.
|
||||||
|
|
||||||
|
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-ops/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.
|
||||||
|
- Example: split a refactoring common core plus two app integrations under `agent-task/refactoring/` as `01_core`, `02+01_edge_integration`, `03+01_node_integration`. Both integrations depend only on `01_core` and may run in parallel after `01_core` has `complete.log`.
|
||||||
|
- Example: split three sequential tasks under one task group as `01_schema`, `02+01_migration`, `03+02_api`.
|
||||||
|
- Example: split independent docs/UI plus an integration under one task group as `01_core`, `02+01_db`, `03+02_api`, `04_docs`, `05_ui`, `06+05_integration`; `01_core`, `04_docs`, and `05_ui` can start together, and `06+05_integration` waits only for `05_ui`.
|
||||||
|
- Preserve task group and subtask directory names verbatim; do not normalize, reinterpret, or choose execution order by agent judgment.
|
||||||
|
|
||||||
|
Routing rules:
|
||||||
|
|
||||||
|
- Build defaults to `local` when the plan is explicit, tests are runnable, and failure is review-detectable.
|
||||||
|
- Use `cloud` for weak tests, broad API/call-site impact, ambiguity, storage/concurrency/protocol/auth risk, or prior local failure.
|
||||||
|
- Use `cloud-G07` or higher for terminal-agent work: shell/CLI workflow implementation, bin script orchestration, process control, stdout/stderr parsing, exit-status contracts, long-running command diagnosis, or terminal benchmark-style tasks. Merely running deterministic tests such as `go test` does not make a task terminal-agent work.
|
||||||
|
- Use `cloud-G07` or higher when acceptance depends on a real interactive external tool, TUI, PTY, browser, screen repaint/cursor stream, or bin-level smoke output. This is mandatory when unit tests pass but the real smoke/integration command fails.
|
||||||
|
- Use `cloud-G07` or higher when a prior review found verification trust failure, reconstructed command output, or claimed stdout/stderr that does not match a rerun.
|
||||||
|
- Keep high-risk design judgment on `cloud` with a higher grade; the runtime may map `cloud-GNN` to frontier-class models.
|
||||||
|
- Review may be `local` for narrow/low-risk checks and `cloud` for multi-file/API/test-meaning reviews, security/auth, storage/migration, concurrency, protocol/schema, cross-domain, or repeated Required issues.
|
||||||
|
- Raise `GNN` with scope, ambiguity, missing tests, irreversible behavior, and blast radius; keep grade model-independent.
|
||||||
|
|
||||||
|
Directory states:
|
||||||
|
|
||||||
|
| State | Meaning |
|
||||||
|
|-------|---------|
|
||||||
|
| `PLAN-*-G??.md` only | Invalid; plan skill always writes both active files |
|
||||||
|
| `PLAN-*-G??.md` + `CODE_REVIEW-*-G??.md` stub | Implementation is pending/in progress |
|
||||||
|
| `PLAN-*-G??.md` + filled `CODE_REVIEW-*-G??.md` | Ready for code-review skill |
|
||||||
|
| `complete.log` + `*.log` files | Task complete (PASS), before final task-directory archive move |
|
||||||
|
| `agent-task/archive/YYYY/MM/{task_name}/complete.log` + `*.log` files | Archived completed task path (PASS); not active |
|
||||||
|
| Only `*.log` files (no `complete.log`) | Task terminated mid-loop or abandoned |
|
||||||
|
|
||||||
|
## Step 1 - Determine Task
|
||||||
|
|
||||||
|
If the user names the task explicitly, use that task group or task path.
|
||||||
|
|
||||||
|
Otherwise, find active plan files with both globs, excluding `agent-task/archive/**`:
|
||||||
|
|
||||||
|
- `agent-task/*/PLAN-*-G??.md`
|
||||||
|
- `agent-task/*/*/PLAN-*-G??.md`
|
||||||
|
|
||||||
|
| 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 ask which task to use; do not choose by agent judgment. |
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
로드맵 확인:
|
||||||
|
|
||||||
|
- `agent-ops/roadmap/current.md`가 있으면 구현 계획 파일을 만들기 전에 읽고, 사용자 요청, 브랜치, 변경 경로를 기준으로 관련 Phase와 Milestone을 선택한다.
|
||||||
|
- `current.md`가 `agent-ops/roadmap/archive/**`를 가리키면 해당 문서는 읽지 말고 활성 Phase/Milestone이 아니라고 보고한다.
|
||||||
|
- 선택한 Phase를 한 번 읽어 Phase 목표, Milestone 흐름, Phase 경계를 확인한다.
|
||||||
|
- 선택한 Milestone을 한 번 읽어 목표, 범위, 필수 기능, 완료 기준, 완료 리뷰, 범위 제외, 구현 잠금을 확인한다. `구현 잠금` 섹션이 없거나 상태가 `잠금`이면 현재 요청에 직접 영향을 주는 `결정 필요` 항목만 확인하고, 그 결정 없이는 `PLAN-*-G??.md`, `CODE_REVIEW-*-G??.md`, file/API/package 수준 구현 단계를 확정하지 않는다.
|
||||||
|
- Phase 또는 Milestone 후보가 여럿이면 요청 문장, 변경 경로 직접성, Milestone 상태, 구현 잠금, 선후 의존성, Phase/Milestone 흐름상 위치를 기준으로 1순위와 2순위를 추천하고 필요한 후보 문서만 읽어 범위를 좁힌다.
|
||||||
|
- 로드맵 current가 있고 활성 Phase/Milestone 밖 작업이면 `ROADMAP.md`의 Phase 흐름을 확인하고 전환, 신규 Phase/Milestone, 또는 기존 활성 범위 내 배치 필요성을 보고한다.
|
||||||
|
- 현재 요청과 직접 관련 없는 미정 항목은 잠금 상태로 남겨도 되며, 기존 구조, 도메인 rule, 플랫폼 관례로 정할 수 있는 세부는 표준선/가정으로 계획에 기록하고 진행할 수 있다.
|
||||||
|
- 사용자가 선택한 Milestone의 작업, 구현, 계획 작성을 명시했고 현재 계획에 필요한 결정이 모두 정해져 있다면 계획 작성을 이어간다. Milestone 전체에서 사용자만 결정할 항목이 더 이상 없을 때만 roadmap update 흐름으로 `구현 잠금` 상태를 `해제`로 갱신한다. 현재 요청에 직접 걸리는 결정이 필요하면 그 항목만 체크리스트로 남기고 사용자에게 확인한다.
|
||||||
|
- 선택한 활성 Milestone 범위에 속하는 구현 계획이면 `{task_group}`을 `m-<milestone-slug>`로 정한다. `<milestone-slug>`는 선택한 Milestone 경로의 파일명에서 `.md`를 제거한 값이다.
|
||||||
|
- 같은 Milestone에서 split work가 필요하면 기존 split 규칙 그대로 `agent-task/m-<milestone-slug>/<subtask_dir>/` 아래에 계획 파일을 만든다.
|
||||||
|
- roadmap/current 파일이 없으면 기존 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 any files. Work through them in order; do not proceed to the next step until every checkbox is done.
|
||||||
|
|
||||||
|
- [ ] **Read all source files in full** — read every source file the change will touch, whole file. No partial reads.
|
||||||
|
- [ ] **Read all test files in full** — read every test file that exercises the changed behavior.
|
||||||
|
- [ ] **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.
|
||||||
|
- [ ] **Grep all symbol references** — for any renamed or removed symbol, find every call site and import chain.
|
||||||
|
- [ ] **Check dependency manifests** — before adding any new package, verify its presence in go.mod / package manifest.
|
||||||
|
- [ ] **Pre-check compile issues** — identify missing interface implementations, type mismatches, and broken imports.
|
||||||
|
- [ ] **Verify verification commands** — confirm that the final verification commands actually run in this repository layout.
|
||||||
|
- [ ] **Stabilize fragile verification** — for search or generated-output checks, choose deterministic commands up front, such as `rg --sort path`, and decide whether cached test output is acceptable or `-count=1` is required.
|
||||||
|
|
||||||
|
## Step 3 - Determine GXX Grade
|
||||||
|
|
||||||
|
GXX is an output of analysis, not an input. Determine lane and grade only after Step 2 is fully complete.
|
||||||
|
|
||||||
|
- [ ] **Assess change scope** — count affected files, interface impact, and call-site count.
|
||||||
|
- [ ] **Check risk factors** — mark any that apply: concurrency, storage/migration, protocol/schema, auth, irreversible behavior.
|
||||||
|
- [ ] **Evaluate test confidence** — judge whether existing tests sufficiently verify the changed behavior.
|
||||||
|
- [ ] **Decide lane** — use `local` if the plan is explicit and tests are sufficient; use `cloud` if any of the following apply:
|
||||||
|
- Tests are weak or do not cover the changed behavior
|
||||||
|
- Broad API/call-site impact
|
||||||
|
- Concurrency, storage, protocol, or auth risk
|
||||||
|
- Prior local build failure on this task
|
||||||
|
- Terminal-agent work: shell/CLI workflow implementation, bin script orchestration, process control, stdout/stderr parsing, exit-status contracts, long-running command diagnosis, or terminal benchmark-style tasks
|
||||||
|
- Real bin/smoke/integration verification failed after unit tests passed
|
||||||
|
- Interactive TUI/PTY/browser/external CLI automation or screen-rendered output is part of the success condition
|
||||||
|
- A prior review marked verification trust Fail/Warn because recorded command output did not match a rerun
|
||||||
|
- [ ] **Decide GNN** — assign a higher grade as scope, ambiguity, irreversibility, and blast radius increase. Grade is complexity-based, not model-name-based.
|
||||||
|
|
||||||
|
## Step 4 - Archive Existing Active Files
|
||||||
|
|
||||||
|
Before writing new active files for the chosen active task directory:
|
||||||
|
|
||||||
|
- Count existing `agent-task/{task_name}/plan_*.log`; call it `N`. If `PLAN-*-G??.md` exists in that same directory, rename `PLAN-{build_lane}-GNN.md` to `plan_{build_lane}_GNN_N.log`.
|
||||||
|
- Count existing `agent-task/{task_name}/code_review_*.log`; call it `M`. If `CODE_REVIEW-*-G??.md` exists in that same directory, rename `CODE_REVIEW-{review_lane}-GNN.md` to `code_review_{review_lane}_GNN_M.log`.
|
||||||
|
|
||||||
|
The new plan number is the count of `plan_*.log` after archiving.
|
||||||
|
|
||||||
|
## Step 5 - Write Plan File
|
||||||
|
|
||||||
|
Header line must be exactly:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
<!-- task={task_name} plan={N} tag={TAG} -->
|
||||||
|
```
|
||||||
|
|
||||||
|
Required sections:
|
||||||
|
|
||||||
|
- Title.
|
||||||
|
- `이 파일을 읽는 구현 에이전트에게`: warn that filling implementation-owned `CODE_REVIEW-*-G??.md` sections is mandatory. Tell the implementer to run verification, fill actual notes/output, keep active files in place, and report ready for review; finalization is code-review-skill only.
|
||||||
|
- `배경`: 2-4 sentences explaining why the work is needed.
|
||||||
|
- `분석 결과`: record the findings from Step 2 and Step 3. This section is the written output of the analysis — not a summary, but the actual findings that justify the plan's scope and decisions. Must include all of the following subsections:
|
||||||
|
- `읽은 파일`: list every source and test file read during analysis, with path.
|
||||||
|
- `테스트 커버리지 공백`: list 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.
|
||||||
|
- `범위 결정 근거`: state which files or areas were explicitly excluded from this change and why. This is the boundary justification — the implementing agent must not silently expand scope beyond what is recorded here.
|
||||||
|
- `빌드 등급`: state the decided lane and GNN grade with a one-line rationale.
|
||||||
|
- `구현 체크리스트`: a top-level checklist the implementing agent must follow while coding. Include one item per plan item, one item for all intermediate/final verification, 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. 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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
- 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 the plan's pass condition says all leftovers must be intentional exceptions, any `변경 필요` item forces FAIL until resolved or explicitly reclassified with evidence.
|
||||||
|
- Decide in the plan whether Go test cache output is acceptable. If fresh execution matters, use `go test -count=1 ...`.
|
||||||
|
|
||||||
|
## Step 6 - Write Review Stub
|
||||||
|
|
||||||
|
Use the template below exactly. Fill `{…}` placeholders from the plan; everything else is fixed and must not be changed by the implementing agent.
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
<!-- task={task_name} plan={N} tag={TAG} -->
|
||||||
|
|
||||||
|
# Code Review Reference - {TAG}
|
||||||
|
|
||||||
|
> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.**
|
||||||
|
> The task is NOT complete until every implementation-owned section below is filled in.
|
||||||
|
> Complete the `구현 체크리스트`; the final checklist item is mandatory before saving.
|
||||||
|
> Fill implementation-owned sections, then stop with active files in place and report ready for review.
|
||||||
|
> Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, `코드리뷰 전용 체크리스트`) is review-agent-only, even after compaction/resume.
|
||||||
|
> Follow the ownership table at the bottom of this file for which sections you own.
|
||||||
|
|
||||||
|
## 개요
|
||||||
|
|
||||||
|
date={YYYY-MM-DD}
|
||||||
|
task={task_name}, plan={N}, tag={TAG}
|
||||||
|
|
||||||
|
## 이 파일을 읽는 리뷰 에이전트에게
|
||||||
|
|
||||||
|
> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다.
|
||||||
|
|
||||||
|
각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
|
||||||
|
리뷰 완료는 아래 순서까지 끝난 상태를 의미합니다.
|
||||||
|
|
||||||
|
1. 판정을 append한다.
|
||||||
|
2. `CODE_REVIEW-{review_lane}-GNN.md` → `code_review_{review_lane}_GNN_N.log`, `PLAN-{build_lane}-GNN.md` → `plan_{build_lane}_GNN_M.log`로 아카이브한다.
|
||||||
|
3. PASS이면 `complete.log` 작성 후 active task 디렉터리를 `agent-task/archive/YYYY/MM/{task_name}/`로 이동한다. WARN/FAIL이면 다음 active plan/review 파일을 즉시 작성한다.
|
||||||
|
4. PASS이고 task group이 `m-<milestone-slug>`이면 완료 이벤트 메타데이터를 보고한다. roadmap 상태 체크와 `update-roadmap` 호출은 런타임 책임이다.
|
||||||
|
5. 적용 가능한 `코드리뷰 전용 체크리스트` 항목을 최종 `.log` 위치에서 체크한 뒤 보고한다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 구현 항목별 완료 여부
|
||||||
|
|
||||||
|
| 항목 | 완료 여부 |
|
||||||
|
|------|---------|
|
||||||
|
| [{TAG}-1] {item description} | [ ] |
|
||||||
|
| [{TAG}-2] {item description} | [ ] |
|
||||||
|
|
||||||
|
## 구현 체크리스트
|
||||||
|
|
||||||
|
{copy the plan's 구현 체크리스트 items exactly, preserving order and checkbox text}
|
||||||
|
|
||||||
|
## 코드리뷰 전용 체크리스트
|
||||||
|
|
||||||
|
> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다.
|
||||||
|
> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다.
|
||||||
|
|
||||||
|
- [ ] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다.
|
||||||
|
- [ ] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다.
|
||||||
|
- [ ] active `CODE_REVIEW-*-G??.md`를 `code_review_{review_lane}_GNN_N.log`로 아카이브한다.
|
||||||
|
- [ ] active `PLAN-*-G??.md`를 `plan_{build_lane}_GNN_M.log`로 아카이브한다.
|
||||||
|
- [ ] 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이면 다음 active `PLAN-{build_lane}-GNN.md`와 `CODE_REVIEW-{review_lane}-GNN.md`를 작성하고 `complete.log`를 작성하지 않는다.
|
||||||
|
|
||||||
|
## 계획 대비 변경 사항
|
||||||
|
|
||||||
|
_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._
|
||||||
|
|
||||||
|
## 주요 설계 결정
|
||||||
|
|
||||||
|
_구현 에이전트가 주요 설계 결정 사항을 기록한다._
|
||||||
|
|
||||||
|
## 리뷰어를 위한 체크포인트
|
||||||
|
|
||||||
|
{pre-filled from plan — one bullet per review focus area}
|
||||||
|
|
||||||
|
## 검증 결과
|
||||||
|
|
||||||
|
_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._
|
||||||
|
|
||||||
|
필수 규칙:
|
||||||
|
- 검증 명령은 고정된 계약이다. 임의로 대체하지 않는다.
|
||||||
|
- 대체가 필요하면 `계획 대비 변경 사항`에 이유와 대체 명령을 기록한다.
|
||||||
|
- `검증 결과`에는 실제 stdout/stderr를 붙여 넣는다.
|
||||||
|
|
||||||
|
### {TAG}-1 중간 검증
|
||||||
|
```
|
||||||
|
$ {verification command from plan}
|
||||||
|
(output)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 최종 검증
|
||||||
|
```
|
||||||
|
$ {final verification command from plan}
|
||||||
|
(output)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section: completion table, implementation checklist, changes from plan, design decisions, and verification output?**
|
||||||
|
> If anything is blank, go back and fill it in before saving this file.
|
||||||
|
> Leave review-agent-only sections unchanged.
|
||||||
|
```
|
||||||
|
|
||||||
|
Sections and their ownership:
|
||||||
|
|
||||||
|
| Section | Owner | Note |
|
||||||
|
|---------|-------|------|
|
||||||
|
| Header comment, 개요, 리뷰 에이전트 지시 | Fixed at stub creation | Implementing agent must not modify or execute these (archive, complete.log, and task-directory archive move are review-agent only) |
|
||||||
|
| 구현 항목별 완료 여부 (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 |
|
||||||
|
| 리뷰어를 위한 체크포인트 | Fixed at stub creation | Pre-filled from plan |
|
||||||
|
| 검증 결과 (section headings + commands) | Fixed at stub creation | Implementing agent fills in command output only; command changes require a `계획 대비 변경 사항` entry |
|
||||||
|
| 코드리뷰 결과 | Review agent appends | Not included in stub |
|
||||||
|
|
||||||
|
## Naming
|
||||||
|
|
||||||
|
| Tag | Use for |
|
||||||
|
|-----|---------|
|
||||||
|
| `API` | Public API changes |
|
||||||
|
| `REFACTOR` | Internal refactoring |
|
||||||
|
| `TEST` | Test additions/fixes |
|
||||||
|
| `REVIEW_<TAG>` | Follow-up fixes after review |
|
||||||
|
|
||||||
|
## Final Checklist
|
||||||
|
|
||||||
|
- `PLAN-{build_lane}-GNN.md` and `CODE_REVIEW-{review_lane}-GNN.md` both exist under the active task directory `agent-task/{task_name}/`.
|
||||||
|
- Single-plan work stores active files directly under `agent-task/{task_group}/`.
|
||||||
|
- Split work, if any, uses one shared `agent-task/{task_group}/` parent and one subtask directory per plan/review pair with names like `01_core`, `02+01_edge_integration`, `03+01_node_integration`; dependency details live in the subtask directory name as `NN+PP[,QQ...]_subtask_name`.
|
||||||
|
- Milestone-linked work uses `agent-task/m-<milestone-slug>/` as the task group; non-roadmap task groups do not start with `m-`.
|
||||||
|
- Both first lines match `<!-- task={task_name} plan={N} tag={TAG} -->`.
|
||||||
|
- Previous active files, if any, were archived with correct numeric suffixes.
|
||||||
|
- Every plan item has problem, solution, checklist, test decision, and intermediate verification.
|
||||||
|
- The plan and review stub have matching `구현 체크리스트` item text/order, and the final checkbox is the mandatory `CODE_REVIEW-*-G??.md` completion item.
|
||||||
|
- The review stub has a clearly marked `코드리뷰 전용 체크리스트` owned only by the review agent.
|
||||||
|
- Routed review file completion table lists every plan item.
|
||||||
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 create grouped PLAN/CODE_REVIEW task files for this repository change."
|
||||||
17
agent-ops/skills/common/router.md
Normal file
17
agent-ops/skills/common/router.md
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
# 공통 스킬 라우터
|
||||||
|
|
||||||
|
| 요청 키워드 | 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` |
|
||||||
|
| README 작성해줘, README 만들어줘, 프로젝트 설명 문서 만들어줘 | `agent-ops/skills/common/create-readme/SKILL.md` |
|
||||||
|
| 로드맵 만들어줘, roadmap 생성, 마일스톤 설계, goal/phase 구조 잡아줘 | `agent-ops/skills/common/create-roadmap/SKILL.md` |
|
||||||
|
| 로드맵 업데이트, roadmap 갱신, 로드맵에 추가, 로드맵 작업 추가, 로드맵 기능 추가, 로드맵 Epic 추가, 로드맵 에픽 추가, 로드맵 Task 추가, 로드맵 태스크 추가, 로드맵 테스크 추가, 로드맵 TODO 추가, 마일스톤에 추가, 마일스톤 추가, 마일스톤 갱신, 마일스톤 아카이브, phase 추가, phase 변경, 페이즈 추가, 페이즈 변경, 현재 마일스톤 변경, 로드맵 한국어 전환, 로드맵 번역 | `agent-ops/skills/common/update-roadmap/SKILL.md` |
|
||||||
|
| 지금 작업이 뭐지?, 현재 작업 분석, 어디까지 했지?, 남은 작업 뭐야 | `agent-ops/skills/common/analyze-roadmap-position/SKILL.md` |
|
||||||
|
| 계획 세워줘, 계획 작성해, 계획 만들어줘, 구현 계획, PLAN.md, plan, plan 작성해, plan 만들어줘 | `agent-ops/skills/common/plan/SKILL.md` |
|
||||||
|
| 코드 리뷰해줘, 리뷰 진행해, 리뷰해줘, code review, CODE_REVIEW.md, 리뷰 루프 | `agent-ops/skills/common/code-review/SKILL.md` |
|
||||||
|
| 커밋해줘, 푸시해줘, commit, push, 반영해줘 | `agent-ops/skills/common/commit-push/SKILL.md` |
|
||||||
|
| agent-ops 싱크해, agent-ops 동기화해, agentic-framework에 올려줘, agent-ops를 [프로젝트]로 싱크해 | `agent-ops/skills/common/sync-push/SKILL.md` |
|
||||||
|
| agent-ops pull해, agent-ops 가져와, agentic-framework에서 가져와, agent-ops 내려받아 | `agent-ops/skills/common/sync-pull/SKILL.md` |
|
||||||
|
| 도메인 업데이트, domain rule 갱신, 도메인 검토, domain 스캔 | `agent-ops/skills/common/update-domain-rule/SKILL.md` |
|
||||||
40
agent-ops/skills/common/sync-pull/SKILL.md
Normal file
40
agent-ops/skills/common/sync-pull/SKILL.md
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
---
|
||||||
|
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를 내려받는다.
|
||||||
|
|
||||||
|
## 언제 호출할지
|
||||||
|
|
||||||
|
- "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`와 일치하는가
|
||||||
|
- [ ] `.geminiignore`, `.aiexclude`, `.cursorignore`, `.clineignore`에 Agent-Ops 관리 block이 있고 그 안에 `agent-task/archive/**`와 `agent-ops/roadmap/archive/**`가 포함되어 있는가
|
||||||
|
- [ ] `.claude/settings.json`, `opencode.json`에 `agent-task/archive/**` hard deny가 있고 `agent-ops/roadmap/archive/**` hard read deny를 새로 추가하지 않았는가
|
||||||
|
- [ ] 현재 프로젝트에 기존 `agent-ops/roadmap/archive/**` hard deny가 있으면 자동 삭제하지 않고 사용자 확인 대상으로 보고했는가
|
||||||
|
- [ ] agentic-framework의 AI ignore / permission 파일은 수정되거나 stage되지 않았는가
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- sync.sh 를 거치지 않고 직접 파일을 복사하지 않는다
|
||||||
101
agent-ops/skills/common/sync-push/SKILL.md
Normal file
101
agent-ops/skills/common/sync-push/SKILL.md
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
---
|
||||||
|
name: sync-push
|
||||||
|
description: 현재 프로젝트의 agent-ops를 agentic-framework로 올리거나, agentic-framework의 공통 agent-ops를 대상 프로젝트 또는 상위 폴더의 agent-ops 적용 프로젝트 전체로 push하고 푸시한다. "agent-ops 싱크해", "agent-ops 동기화해", "agentic-framework에 올려줘" 요청 시 사용한다.
|
||||||
|
---
|
||||||
|
|
||||||
|
# sync-push
|
||||||
|
|
||||||
|
## 목적
|
||||||
|
|
||||||
|
`agent-ops/bin/sync.sh`를 호출해 agent-ops 공통 파일을 push 방향으로 동기화한다.
|
||||||
|
|
||||||
|
- 일반 프로젝트에서는 현재 프로젝트 → agentic-framework 방향으로 올린다.
|
||||||
|
- agentic-framework 원본 프로젝트에서는 agentic-framework → 대상 프로젝트 방향으로 보내고, 대상 repo를 commit/push 한다.
|
||||||
|
- agentic-framework 원본 프로젝트에서 대상이 명시되지 않으면 현재 프로젝트의 상위 폴더에 있는 agent-ops 적용 프로젝트 전체로 보낸다.
|
||||||
|
|
||||||
|
## 버전 정책
|
||||||
|
|
||||||
|
- `agentic-framework` 원본 프로젝트에서 대상 프로젝트로 전파하는 push 동기화는 버전을 올리지 않는다.
|
||||||
|
- 이 경우 현재 `agentic-framework`의 `agent-ops/.version` 값을 그대로 대상 repo에 전파한다.
|
||||||
|
- 일반 프로젝트에서 `agentic-framework`로 공통 변경을 올리는 push 동기화는 기존처럼 `sync.sh`가 버전을 한 단계 올린다.
|
||||||
|
|
||||||
|
## 언제 호출할지
|
||||||
|
|
||||||
|
- "agent-ops 싱크해", "agent-ops 동기화해" 요청 시
|
||||||
|
- "agentic-framework에 올려줘" 요청 시
|
||||||
|
- "agent-ops를 [프로젝트]로 싱크해" 요청 시
|
||||||
|
|
||||||
|
## 실행 절차
|
||||||
|
|
||||||
|
### 현 프로젝트가 일반 프로젝트인 경우 (`.agent-ops-source` 없음)
|
||||||
|
|
||||||
|
1. 현재 프로젝트의 **상위 폴더(`../`)** 에 `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. 공통 관리 파일 변경이 있으면 `sync.sh`가 버전을 한 단계 올리고 현재 프로젝트와 `agentic-framework`에 같은 버전을 반영한다
|
||||||
|
6. 일반 프로젝트에서 agentic-framework로 올릴 때는 AI ignore / permission 파일을 보강하거나 stage하지 않는다
|
||||||
|
|
||||||
|
### 현 프로젝트가 agentic-framework인 경우 (`.agent-ops-source` 있음)
|
||||||
|
|
||||||
|
1. 사용자 요청에서 target 프로젝트명 또는 경로를 추출한다
|
||||||
|
2. **명시된 경우**: `agent-ops/bin/sync.sh <target>` 실행
|
||||||
|
3. **명시되지 않은 경우**: `agent-ops/bin/sync.sh` 실행
|
||||||
|
4. target이 없으면 `sync.sh`가 현재 프로젝트 기준 상위 폴더(`../`)의 하위 디렉터리 중 `agent-ops/` 폴더가 있는 프로젝트를 모두 대상으로 삼는다
|
||||||
|
5. `sync.sh`는 현재 agentic-framework의 `agent-ops/rules/common/rules.md` 내용을 대상 프로젝트 루트의 진입 파일에 덮어쓴다
|
||||||
|
6. 적용 후 각 대상 repo에서 agent-ops 공통 관리 경로(`rules/common/rules.md` 포함), 진입 파일, AI ignore / permission 파일을 stage 하여 commit/push 한다
|
||||||
|
7. AI ignore / permission 파일은 대상 프로젝트의 기존 내용을 덮어쓰지 않고, Agent-Ops 관리 block 또는 Agent-Ops 전용 permission key만 보강한다
|
||||||
|
8. 이 과정에서는 버전을 새로 올리지 않고 현재 agentic-framework의 `agent-ops/.version` 값을 그대로 대상 프로젝트에 반영한다
|
||||||
|
|
||||||
|
덮어쓰기 대상은 `init-agent-ops` 초기 세팅과 동일하며, 실제 목록은 `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` |
|
||||||
|
|
||||||
|
대상 프로젝트에 기존 진입 파일이 있어도 보존하거나 병합하지 않고 `agent-ops/rules/common/rules.md` 내용으로 교체한다.
|
||||||
|
|
||||||
|
## AI Ignore / Permission 재적용
|
||||||
|
|
||||||
|
- 이 절차는 agentic-framework 원본 프로젝트에서 대상 프로젝트로 push할 때와 `--pull`로 agentic-framework에서 현재 프로젝트로 내려받을 때만 적용한다.
|
||||||
|
- 일반 프로젝트에서 agentic-framework로 올리는 push에서는 AI ignore / permission 파일을 수정하거나 stage하지 않는다.
|
||||||
|
- `.geminiignore`, `.aiexclude`, `.cursorignore`, `.clineignore`는 사용자 영역을 수정하지 않고 아래 관리 block만 추가하거나 교체한다.
|
||||||
|
|
||||||
|
```text
|
||||||
|
# BEGIN Agent-Ops managed ignore
|
||||||
|
agent-task/archive/**
|
||||||
|
agent-ops/roadmap/archive/**
|
||||||
|
# END Agent-Ops managed ignore
|
||||||
|
```
|
||||||
|
|
||||||
|
- 관리 block 밖의 기존 ignore 항목은 사용자 소유로 보고 삭제, 정렬, 중복 제거하지 않는다.
|
||||||
|
- `.claude/settings.json`과 `opencode.json`은 기존 사용자 설정을 보존하고 `agent-task/archive/**` hard read/glob deny만 보강한다.
|
||||||
|
- `agent-ops/roadmap/archive/**`는 필요한 경우 링크로 읽을 수 있어야 하므로 `.claude/settings.json`이나 `opencode.json`의 hard read deny로 새로 추가하지 않는다.
|
||||||
|
- 대상 프로젝트에 기존 `agent-ops/roadmap/archive/**` hard read/glob deny가 있으면 사용자 설정으로 보고 자동 삭제하지 않고 경고만 남긴다.
|
||||||
|
- `opencode.json`의 watcher ignore에는 `agent-task/archive/**`와 `agent-ops/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`의 진입 파일로 제한한다. AI ignore / permission 파일은 framework에서 일반 프로젝트로 내려보내는 경우에만 대상 repo에서 추가 stage한다.
|
||||||
|
|
||||||
|
## 실행 결과 검증
|
||||||
|
|
||||||
|
- [ ] sync.sh 가 오류 없이 완료됐는가
|
||||||
|
- [ ] 버전 충돌 경고가 없었는가 — 있었다면 사용자에게 수동 머지 필요함을 알린다
|
||||||
|
- [ ] 대상 repo의 `agent-ops/rules/common/rules.md`가 현재 agentic-framework의 `agent-ops/rules/common/rules.md`와 일치하는가
|
||||||
|
- [ ] agentic-framework에서 대상 프로젝트로 push한 경우, `agent-ops/bin/entry-files.sh`의 모든 진입 파일 내용이 현재 agentic-framework의 `agent-ops/rules/common/rules.md`와 일치하는가
|
||||||
|
- [ ] framework에서 대상 프로젝트로 push한 경우, `.geminiignore`, `.aiexclude`, `.cursorignore`, `.clineignore`에 Agent-Ops 관리 block이 있고 그 안에 `agent-task/archive/**`와 `agent-ops/roadmap/archive/**`가 포함되어 있는가
|
||||||
|
- [ ] framework에서 대상 프로젝트로 push한 경우, `.claude/settings.json`과 `opencode.json`에 `agent-task/archive/**` hard deny가 있고 `agent-ops/roadmap/archive/**` hard read deny를 새로 추가하지 않았는가
|
||||||
|
- [ ] 대상 프로젝트에 기존 `agent-ops/roadmap/archive/**` hard deny가 있으면 자동 삭제하지 않고 사용자 확인 대상으로 보고했는가
|
||||||
|
- [ ] 일반 프로젝트에서 agentic-framework로 push한 경우, AI ignore / permission 파일이 agentic-framework에 유입되지 않았는가
|
||||||
|
- [ ] 대상 repo에 commit/push 된 path가 방향별 허용 범위로 제한되었는가
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- sync.sh 를 거치지 않고 직접 파일을 복사하지 않는다
|
||||||
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 파일 갱신만 담당한다
|
||||||
331
agent-ops/skills/common/update-roadmap/SKILL.md
Normal file
331
agent-ops/skills/common/update-roadmap/SKILL.md
Normal file
|
|
@ -0,0 +1,331 @@
|
||||||
|
---
|
||||||
|
name: update-roadmap
|
||||||
|
version: 1.17.0
|
||||||
|
description: 로드맵 업데이트, 로드맵에 추가, 마일스톤 추가/갱신, phase/페이즈 변경 요청에 사용한다. Roadmap-Phase-Milestone scaffold에서 target 없는 신규 작업의 규모를 판정하고 기존 Phase/Milestone/Epic/Task를 검색해 upsert한 뒤, 없을 때만 새 항목을 만들고 current.md 동기화, runtime m-task 완료 이벤트 반영, 완료 후보 검토중 전환, 승인된 archive 이동을 처리한다.
|
||||||
|
---
|
||||||
|
|
||||||
|
# 로드맵 업데이트
|
||||||
|
|
||||||
|
## 목적
|
||||||
|
|
||||||
|
기존 `agent-ops/roadmap/` 구조를 현재 프로젝트 방향과 진행 상태에 맞게 갱신한다.
|
||||||
|
표준 구조는 `ROADMAP.md -> phase/<phase-slug>/PHASE.md -> phase/<phase-slug>/milestones/<milestone-slug>.md`다.
|
||||||
|
archive도 같은 Phase scaffold를 유지하며 `archive/phase/<phase-slug>/...` 아래에 둔다.
|
||||||
|
로드맵 전체를 매 작업마다 읽지 않도록 유지하면서, `current.md`의 활성 Phase와 활성 Milestone 창이 실제 작업 후보 목록으로 동작하게 한다.
|
||||||
|
|
||||||
|
Milestone은 구현 계획이 아니라 방향성, 범위, 위험, 확인 필요 사항을 기록하는 협업 문서로 유지한다.
|
||||||
|
Epic과 Task는 별도 파일로 분리하지 않고 Milestone 문서의 `필수 기능` 안에서 관리한다.
|
||||||
|
|
||||||
|
## 언제 호출할지
|
||||||
|
|
||||||
|
- 사용자가 "로드맵 업데이트", "마일스톤 갱신", "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로 마이그레이션하거나 표준화해야 할 때
|
||||||
|
|
||||||
|
## 입력
|
||||||
|
|
||||||
|
- `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` 중 하나 (선택)
|
||||||
|
- `lock-state`: Milestone 구현 잠금 상태. `잠금` / `해제` 중 하나 (선택)
|
||||||
|
- `decision-needed`: `구현 잠금`에 남길 사용자만 결정할 수 있는 질문 목록 (선택)
|
||||||
|
- `evidence`: 완료 판단에 사용할 파일, PR, 테스트, 커밋, 사용자 설명 (선택)
|
||||||
|
- `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 아카이브 날짜. 없으면 현재 날짜를 사용한다 (선택)
|
||||||
|
|
||||||
|
## 표준 구조
|
||||||
|
|
||||||
|
```text
|
||||||
|
agent-ops/roadmap/
|
||||||
|
ROADMAP.md
|
||||||
|
current.md
|
||||||
|
phase/
|
||||||
|
<phase-slug>/
|
||||||
|
PHASE.md
|
||||||
|
milestones/
|
||||||
|
<milestone-slug>.md
|
||||||
|
archive/
|
||||||
|
phase/
|
||||||
|
<phase-slug>/
|
||||||
|
PHASE.md
|
||||||
|
milestones/
|
||||||
|
<milestone-slug>.md
|
||||||
|
```
|
||||||
|
|
||||||
|
- `ROADMAP.md`는 전체 목표와 Phase 흐름만 담는다.
|
||||||
|
- `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/`만 있을 수 있다.
|
||||||
|
- `<phase-slug>`와 `<milestone-slug>`는 소문자 영문, 숫자, 하이픈만 사용한다.
|
||||||
|
- `current.md`는 활성 Phase와 활성 Milestone을 모두 가리킨다.
|
||||||
|
- `current.md`에는 archive 경로를 넣지 않는다.
|
||||||
|
- `current.md`에는 `[완료]` 또는 `[폐기]` Phase/Milestone을 남기지 않는다. 완료 후보는 사용자 승인 전까지 `[검토중]`으로 둔다.
|
||||||
|
|
||||||
|
## 상태와 id
|
||||||
|
|
||||||
|
- 상태 표기는 `[계획]`, `[진행중]`, `[검토중]`, `[완료]`, `[보류]`, `[폐기]` 중 하나만 사용한다.
|
||||||
|
- 기존 비표준 상태 표기는 갱신 범위에 포함될 때 표준 상태 표기로 정리한다.
|
||||||
|
- `[검토중]`은 모든 필수 작업과 완료 기준이 충족된 것으로 보이나, 사용자 최종 확인과 archive 승인이 남은 완료 후보 상태다.
|
||||||
|
- 검토 결과 보완이 필요하면 별도 reopen 상태를 만들지 않고 `[진행중]`으로 되돌린 뒤 `완료 리뷰` 또는 `작업 컨텍스트`에 보완 방향을 남긴다.
|
||||||
|
- 검토 결과 보류 또는 폐기 결정이 나면 `[보류]` 또는 `[폐기]`로 전환한다.
|
||||||
|
- `ROADMAP.md`의 Phase 흐름과 `PHASE.md`의 Milestone 흐름은 완료, 검토중, 진행중, 계획 순서를 기본으로 하며 아래로 갈수록 미래 작업에 가까워지게 정렬한다.
|
||||||
|
- 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을 우선 읽는다.
|
||||||
|
- `ROADMAP.md`는 Phase 흐름, 전체 구조, 활성 범위 밖 작업, 전체 재계획, archive 링크 갱신이 필요할 때 읽는다.
|
||||||
|
- `agent-ops/roadmap/archive/**`는 일반 작업이나 sync에서 읽지 않는다.
|
||||||
|
- archive 모드에서 이동 대상이 아직 활성 경로에 있으면 그 대상 문서는 읽을 수 있다.
|
||||||
|
- 과거 완료 내용, 완료 근거, 복원, 비교가 필요한 요청이면 `ROADMAP.md` 또는 `PHASE.md`의 archive 링크를 따라 필요한 archive 문서만 읽는다.
|
||||||
|
|
||||||
|
## 템플릿
|
||||||
|
|
||||||
|
- `ROADMAP.md`: `agent-ops/skills/common/_templates/roadmap-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`
|
||||||
|
|
||||||
|
## 구현 잠금
|
||||||
|
|
||||||
|
- `구현 잠금`은 승인 절차가 아니라 사용자 결정이 필요한지 표시하는 얇은 상태다.
|
||||||
|
- 사용자만 결정할 수 있는 제품 방향, 범위, 우선순위, 책임 경계가 남아 있으면 `잠금`으로 두고 `결정 필요` 체크리스트에 질문을 적는다.
|
||||||
|
- 기존 구조, 도메인 rule, 플랫폼 관례, 업계 표준으로 합리적으로 정할 수 있는 항목은 `결정 필요`가 아니라 `작업 컨텍스트`의 표준선으로 기록한다.
|
||||||
|
- Milestone 전체에서 사용자만 결정할 항목이 더 이상 없고 에이전트가 표준선에 따라 실행하면 되는 상태라면 `해제`로 둔다.
|
||||||
|
- 잠금 상태 변경은 Milestone 완료 판정이 아니므로 `필수 기능`과 `완료 기준`을 자동 완료 처리하지 않는다.
|
||||||
|
|
||||||
|
## 완료 리뷰와 검토중 상태
|
||||||
|
|
||||||
|
- Task 완료 또는 Milestone 갱신 후 필수 Epic/Task와 `완료 기준`이 모두 evidence와 함께 `[x]`인지 확인한다.
|
||||||
|
- 모두 충족된 것으로 보이면 Milestone을 `[완료]`로 바로 바꾸거나 archive로 이동하지 말고 `[검토중]`으로 바꾼다.
|
||||||
|
- `[검토중]`으로 바꿀 때는 Milestone 문서의 `완료 리뷰` 섹션을 만들거나 갱신한다.
|
||||||
|
- `완료 리뷰`에는 `상태: 요청됨`, `요청일`, 완료 근거 1~3줄, 사용자 최종 확인 항목, 리뷰 코멘트를 남긴다.
|
||||||
|
- 사용자가 승인하면 `완료 리뷰`를 `상태: 승인됨`으로 바꾸고 Milestone 상태를 `[완료]`로 전환한 뒤 archive 모드를 수행한다.
|
||||||
|
- 사용자가 보완을 요구하면 `완료 리뷰`를 `상태: 보완 필요`로 바꾸고 Milestone 상태를 `[진행중]`으로 되돌린다. 이때 보완 방향을 `완료 리뷰` 또는 `작업 컨텍스트`에 남기며 별도 reopen 상태는 만들지 않는다.
|
||||||
|
- 사용자가 보류 또는 폐기를 지시하면 `완료 리뷰`와 Milestone 상태를 각각 `보류`/`[보류]`, `폐기`/`[폐기]`로 맞춘다. `[폐기]`는 archive 대상이 될 수 있다.
|
||||||
|
- Phase는 하위 Milestone이 모두 `[완료]` 또는 `[폐기]`로 정리되고 Phase 목표도 충족된 것으로 보일 때 `[검토중]`으로 두고, 사용자 승인 후 `[완료]` 또는 `[폐기]`로 archive한다.
|
||||||
|
|
||||||
|
## Milestone task group 연동
|
||||||
|
|
||||||
|
- 런타임 완료 이벤트의 `origin-task`에서 `agent-task/` 다음 첫 path segment가 `m-<milestone-slug>`이면 Milestone 기반 plan/review 완료에서 온 요청으로 본다. `origin-task`는 archive 이동 전 active task 경로 또는 런타임이 그 형태로 정규화한 경로를 사용한다.
|
||||||
|
- `<milestone-slug>`는 활성 `agent-ops/roadmap/phase/*/milestones/<milestone-slug>.md`에서 정확히 하나만 찾아야 한다. archive Milestone은 target 후보가 아니다.
|
||||||
|
- target이 없거나 둘 이상이면 Milestone 내용을 추정해 수정하지 말고 target 불명확으로 보고한다.
|
||||||
|
- target이 확정되면 PASS evidence, `complete.log`, final archive path, archived plan/review log 경로, code-review 결과 요약을 근거로 해당 Milestone의 Epic/Task와 완료 기준을 갱신한다. target routing 자체는 완료 이벤트의 `m-<milestone-slug>` task group으로만 결정한다.
|
||||||
|
- 갱신 후 필수 Epic/Task와 완료 기준이 모두 충족되면 `[검토중]` 전환과 `완료 리뷰` 요청 규칙을 적용한다.
|
||||||
|
|
||||||
|
## 삽입 단위 정책
|
||||||
|
|
||||||
|
| 삽입 단위 | 사용 기준 |
|
||||||
|
|-----------|-----------|
|
||||||
|
| 새 Phase | 독립적인 제품 진화 단계와 여러 Milestone 묶음이 필요하다 |
|
||||||
|
| 새 Milestone | 독립적인 목표와 완료 기준이 필요하고 Phase 흐름에 의미 있는 경계를 만든다 |
|
||||||
|
| 새 Epic | 기존 Milestone 안에서 여러 Task를 묶는 상위 capability 또는 산출물이다 |
|
||||||
|
| 새 Task | 기존 Epic 아래에 들어가는 완료 가능한 capability, 산출물, 검증 항목이다 |
|
||||||
|
| 하위 작업 | 기존 Task를 완성하기 위한 구현 세부, 테스트, 문서화, 예외 처리다 |
|
||||||
|
| 작업 컨텍스트/TODO | 사용자 결정 또는 조사/확인이 먼저 필요해 필수 기능으로 확정하기 어렵다 |
|
||||||
|
|
||||||
|
- 먼저 요청 내용의 규모를 판정한다. 배치 위치를 찾기 전에 `phase`, `milestone`, `epic`, `task`, `subtask`, `context` 중 가장 작은 충분한 단위를 고른다.
|
||||||
|
- 가장 작은 충분한 단위 원칙을 따른다. 애매하면 새 Phase나 새 Milestone으로 키우지 말고, 기존 Milestone의 Epic/Task에 넣을 수 있는지 먼저 확인한다.
|
||||||
|
- 위치 지정이 있으면 anchor의 레벨을 먼저 확인한다.
|
||||||
|
- `<epic-id> 아래`는 해당 Epic 아래 Task로 넣는다.
|
||||||
|
- `<item-id> 앞/뒤`는 같은 Epic 안의 형제 Task로 넣는다.
|
||||||
|
- `<item-id> 아래`는 해당 Task의 하위 작업으로 넣는다.
|
||||||
|
- `<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 범위 제외, 선후 의존성과 충돌하면 수정 전에 사용자에게 확인한다.
|
||||||
|
|
||||||
|
## 레벨별 탐색과 upsert 정책
|
||||||
|
|
||||||
|
target 없는 신규 추가 요청은 append가 아니라 upsert로 처리한다.
|
||||||
|
|
||||||
|
1. **요청 정규화**
|
||||||
|
- 요청 문장에서 기능명, 목표, 산출물, 관련 경로/도메인, 완료 기대, 제약, 명시 anchor를 뽑는다.
|
||||||
|
- 사용자가 Phase/Milestone/Epic/Task/id/path를 명시했으면 그 anchor를 우선 후보로 둔다.
|
||||||
|
|
||||||
|
2. **규모 판정**
|
||||||
|
- 여러 Milestone을 묶는 제품/운영 단계면 Phase 규모다.
|
||||||
|
- 독립 목표, 별도 완료 기준, 여러 Epic이 필요한 결과면 Milestone 규모다.
|
||||||
|
- 한 Milestone 안의 capability 묶음이면 Epic 규모다.
|
||||||
|
- Epic 아래에서 완료 가능한 단일 capability, 산출물, 검증 항목이면 Task 규모다.
|
||||||
|
- Task를 완성하기 위한 구현 세부면 subtask 규모다.
|
||||||
|
- 조사, 결정, 보류 질문이면 작업 컨텍스트/TODO 규모다.
|
||||||
|
|
||||||
|
3. **레벨별 탐색**
|
||||||
|
- Phase 후보를 먼저 찾는다. `current.md`의 활성 Phase를 우선 보되, target이 없거나 활성 범위 밖 가능성이 있으면 `ROADMAP.md`의 Phase 흐름도 본다.
|
||||||
|
- 선택한 Phase 안에서 Milestone 후보를 찾는다. 활성 Milestone을 우선 보되, 요청이 계획 Milestone 목표와 더 직접 맞으면 계획 Milestone도 후보로 둔다.
|
||||||
|
- 선택한 Milestone 안에서 Epic 후보를 찾는다. `필수 기능`의 Epic heading, 목표 설명, Task 묶음을 비교한다.
|
||||||
|
- 선택한 Epic 안에서 Task 후보를 찾는다. item-id, 문장 의미, 완료 기준, 관련 경로를 비교한다.
|
||||||
|
- archive 문서는 기본 탐색 대상이 아니다. 사용자가 과거 기록 비교를 명시했거나 완료 내용 확인이 필요한 경우에만 `ROADMAP.md` 또는 `PHASE.md`의 archive 링크를 따라 필요한 문서만 읽는다.
|
||||||
|
|
||||||
|
4. **중복/업데이트 판정**
|
||||||
|
- 같은 id, 같은 제목, 같은 목표, 같은 관련 경로, 같은 완료 기준, 또는 같은 산출물을 다루면 동일/유사 후보로 본다.
|
||||||
|
- 동일 항목이면 새로 만들지 않고 기존 Phase/Milestone/Epic/Task를 업데이트한다.
|
||||||
|
- 기존 항목의 범위를 보강하는 내용이면 해당 항목의 설명, Task, 완료 기준, 작업 컨텍스트 중 알맞은 곳에 병합한다.
|
||||||
|
- 기존 항목과 충돌하거나 범위 제외를 건드리면 수정 전에 사용자에게 확인한다.
|
||||||
|
- 같은 레벨에 적절한 후보가 없을 때만 새 항목을 만든다. 새 항목도 판정한 규모보다 크게 만들지 않는다.
|
||||||
|
- 부모 레벨 후보는 있고 판정 규모의 항목만 없으면, 부모 아래에 판정 규모의 새 항목을 만든다. 부모 레벨도 없을 때만 필요한 부모 항목을 함께 만든다.
|
||||||
|
|
||||||
|
## archive 정책
|
||||||
|
|
||||||
|
### Milestone archive
|
||||||
|
|
||||||
|
- 대상 Milestone이 `[완료]` 또는 `[폐기]`인지 확인한다.
|
||||||
|
- `[검토중]` Milestone은 archive하지 않는다. 사용자 완료 승인 또는 폐기 지시가 있으면 먼저 `[완료]` 또는 `[폐기]`로 바꾼 뒤 archive한다.
|
||||||
|
- 대상 파일을 `agent-ops/roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md`에서 `agent-ops/roadmap/archive/phase/<phase-slug>/milestones/<milestone-slug>.md`로 이동한다.
|
||||||
|
- 활성 `PHASE.md`의 Milestone 흐름에는 `[완료]` 또는 `[폐기]` 항목을 남기고, 경로는 archive 경로로 바꾼다.
|
||||||
|
- `current.md`의 활성 Milestone에서는 제거한다.
|
||||||
|
- `ROADMAP.md`는 Phase 상태나 경로가 바뀌지 않으면 수정하지 않는다.
|
||||||
|
- 이동한 archive 문서는 스냅샷으로 보존하고 최신 템플릿에 맞춰 재포맷하지 않는다.
|
||||||
|
|
||||||
|
### Phase archive
|
||||||
|
|
||||||
|
- Phase 전체가 `[완료]` 또는 `[폐기]`인지 확인한다.
|
||||||
|
- `[검토중]` Phase는 archive하지 않는다. 사용자 완료 승인 또는 폐기 지시가 있으면 먼저 `[완료]` 또는 `[폐기]`로 바꾼 뒤 archive한다.
|
||||||
|
- `agent-ops/roadmap/phase/<phase-slug>/PHASE.md`를 `agent-ops/roadmap/archive/phase/<phase-slug>/PHASE.md`로 이동한다.
|
||||||
|
- 해당 Phase의 하위 Milestone도 `archive/phase/<phase-slug>/milestones/` 아래로 이동한다.
|
||||||
|
- `ROADMAP.md`의 Phase 흐름에는 해당 Phase 항목을 남기고, 상태와 경로를 archive `PHASE.md`로 바꾼다.
|
||||||
|
- `current.md`의 활성 Phase와 활성 Milestone에서는 해당 Phase와 하위 Milestone을 제거한다.
|
||||||
|
- archive 문서는 스냅샷으로 보존하고 최신 템플릿에 맞춰 재포맷하지 않는다.
|
||||||
|
|
||||||
|
## 실행 절차
|
||||||
|
|
||||||
|
1. **갱신 범위 결정**
|
||||||
|
- 요청에서 mode, 대상 Phase/Milestone, placement, placement-unit을 추론한다.
|
||||||
|
- 런타임 완료 이벤트의 `origin-task` task group이 `m-<milestone-slug>`이면 `target-milestone`을 활성 Milestone 경로 매칭으로 확정한다.
|
||||||
|
- 구조 전환, 템플릿 보정, current 동기화는 `sync`로 본다.
|
||||||
|
- 사용자 승인 이후의 완료/폐기 이동은 `archive`로 본다.
|
||||||
|
- 새 기능 배치, Epic/Task 추가는 `milestone` 또는 `phase`로 본다.
|
||||||
|
- "로드맵에 추가"처럼 target이 없는 신규 작업 요청은 `placement=auto`, `placement-unit=auto`, `new-feature=<요청 내용>`으로 본다.
|
||||||
|
|
||||||
|
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 문서의 목표, 범위, 필수 기능, 완료 기준, 완료 리뷰, 범위 제외, 구현 잠금을 확인한다.
|
||||||
|
- Phase -> Milestone -> Epic -> Task 순서로 내려가며 같은 레벨의 동일/유사 후보를 먼저 찾는다.
|
||||||
|
- `current.md`에 archive 경로가 있으면 읽지 말고 제거 대상으로 기록한다.
|
||||||
|
- 필요한 경우에만 `ROADMAP.md`를 읽어 전체 Phase 흐름을 확인한다.
|
||||||
|
|
||||||
|
4. **변경 내용 작성**
|
||||||
|
- `ROADMAP.md`는 전체 목표, Phase 흐름, 로딩 정책이 바뀔 때만 수정한다.
|
||||||
|
- `current.md`는 활성 Phase/Milestone 창이 바뀔 때 수정한다.
|
||||||
|
- `PHASE.md`는 Phase 목표, 상태, Milestone 흐름, Phase 경계가 바뀔 때 수정한다.
|
||||||
|
- Milestone 문서는 목표, 상태, 구현 잠금, 범위, Epic/Task, 완료 기준, 완료 리뷰, 범위 제외, 작업 컨텍스트가 바뀔 때 수정한다.
|
||||||
|
- 동일/유사 후보가 있으면 기존 항목을 업데이트하고 중복 항목을 만들지 않는다.
|
||||||
|
- 새 Milestone은 해당 Phase의 `milestones/` 아래에 만든다.
|
||||||
|
- 새 Epic은 `필수 기능` 아래 `### Epic: [epic-id] <이름>`으로 만든다.
|
||||||
|
- 새 Task는 관련 Epic 아래 `- [ ] [item-id] 설명`으로 만든다.
|
||||||
|
- 새 항목은 레벨별 탐색에서 적절한 기존 후보가 없을 때만 만든다.
|
||||||
|
- 완료 체크는 evidence가 있을 때만 `[x]`로 바꾼다.
|
||||||
|
- 필수 Epic/Task와 완료 기준이 모두 evidence와 함께 `[x]`이면 Milestone 상태를 `[검토중]`으로 바꾸고 `완료 리뷰`에 리뷰 요청과 근거를 남긴다.
|
||||||
|
- `[검토중]` 전환만으로 archive 이동, `current.md` 제거, archive 링크 변경을 수행하지 않는다.
|
||||||
|
- 사용자 승인 근거가 있으면 `[검토중]`을 `[완료]`로 전환하고 archive 모드를 수행할 수 있다.
|
||||||
|
|
||||||
|
5. **검증**
|
||||||
|
- `current.md`의 활성 Phase/Milestone 경로가 실제 파일을 가리키는지 확인한다.
|
||||||
|
- `current.md`의 활성 항목이 archive 경로를 가리키지 않는지 확인한다.
|
||||||
|
- `current.md`의 활성 항목이 `[완료]` 또는 `[폐기]` 상태로 남아 있지 않은지 확인한다.
|
||||||
|
- `ROADMAP.md`의 Phase 경로가 실제 `PHASE.md` 파일을 가리키는지 확인한다.
|
||||||
|
- 각 `PHASE.md`의 Milestone 경로가 실제 파일을 가리키는지 확인한다.
|
||||||
|
- 상태 표기가 표준값인지 확인한다.
|
||||||
|
- `[검토중]` Milestone이 archive 경로로 이동되지 않았는지 확인한다.
|
||||||
|
- 필수 Epic/Task와 완료 기준이 모두 `[x]`인 Milestone에는 `완료 리뷰` 섹션과 사용자 리뷰 요청이 있는지 확인한다.
|
||||||
|
- Epic heading과 Task id 형식이 맞는지 확인한다.
|
||||||
|
- 요청 규모가 판정되었고 결과 보고에 남았는지 확인한다.
|
||||||
|
- 동일/유사 기존 항목을 검색했고 신규/업데이트 판정이 결과 보고에 남았는지 확인한다.
|
||||||
|
- 자동 배치한 신규 작업이면 선택한 후보와 밀린 후보의 근거가 결과 보고에 포함되는지 확인한다.
|
||||||
|
- `git diff --check`로 공백 오류를 확인한다.
|
||||||
|
|
||||||
|
6. **결과 보고**
|
||||||
|
- 수정한 파일 목록
|
||||||
|
- 요청 규모 판정과 근거
|
||||||
|
- Phase -> Milestone -> Epic -> Task 탐색 경로와 후보
|
||||||
|
- 신규 추가인지 기존 항목 업데이트인지
|
||||||
|
- 변경된 Phase / Milestone / 상태
|
||||||
|
- 신규 작업의 삽입 단위와 배치 위치
|
||||||
|
- 자동 배치한 경우 비교한 후보와 선택 근거
|
||||||
|
- current.md 활성 창 변경 사항
|
||||||
|
- 완료 리뷰 상태와 사용자 확인 필요 항목
|
||||||
|
- 런타임 완료 이벤트의 `origin-task`가 `m-<milestone-slug>`이면 원래 active task 경로와 매칭된 target Milestone 또는 target 불명확 사유
|
||||||
|
- archive 모드이면 이동 경로와 남긴 링크
|
||||||
|
- 확인 필요로 남긴 항목
|
||||||
|
|
||||||
|
## 출력 형식
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## 업데이트 완료
|
||||||
|
|
||||||
|
- 모드: <status | milestone | phase | replan | sync | concretize | archive>
|
||||||
|
- 수정 파일:
|
||||||
|
- agent-ops/roadmap/ROADMAP.md
|
||||||
|
- agent-ops/roadmap/current.md
|
||||||
|
- agent-ops/roadmap/phase/<phase-slug>/PHASE.md
|
||||||
|
- agent-ops/roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md
|
||||||
|
- agent-ops/roadmap/archive/phase/<phase-slug>/... (archive 모드)
|
||||||
|
|
||||||
|
## 변경 사항
|
||||||
|
|
||||||
|
- Phase: <변경 없음 | 요약>
|
||||||
|
- Milestone: <변경 없음 | 요약>
|
||||||
|
- 삽입 단위: <Phase | Milestone | Epic | Task | 하위 작업 | 작업 컨텍스트/TODO | 변경 없음>
|
||||||
|
- 규모 판정: <phase | milestone | epic | task | subtask | context | 변경 없음> - <근거>
|
||||||
|
- 탐색 경로: <Phase 후보 -> Milestone 후보 -> Epic 후보 -> Task 후보 | 해당 없음>
|
||||||
|
- 신규/업데이트 판정: <신규 생성 | 기존 항목 업데이트 | 변경 없음> - <동일/유사 후보 근거>
|
||||||
|
- 배치: <사용자 지정 위치 반영 | 자동 배치 위치와 근거 | 변경 없음>
|
||||||
|
- 배치 후보: <자동 배치 시 1순위/2순위 후보와 선택/제외 근거 | 해당 없음>
|
||||||
|
- 템플릿 보정: <ROADMAP | current.md | PHASE | Milestone | 이미 일치 | 변경 없음>
|
||||||
|
- 구현 잠금: <잠금 유지 | 잠금 추가 | 해제 | 변경 없음>; 결정 필요: <없음 | 항목 요약>
|
||||||
|
- 완료 리뷰: <변경 없음 | 요청됨 | 승인됨 | 보완 필요 | 보류 | 폐기>
|
||||||
|
- runtime m-task 라우팅: <해당 없음 | origin-task -> target Milestone | target 불명확>
|
||||||
|
- 활성 항목: <변경 없음 | Phase/Milestone 추가/제거 요약>
|
||||||
|
- 아카이브: <변경 없음 | 이동 경로와 남긴 링크>
|
||||||
|
- 상태: <변경 없음 | 이전 -> 이후>
|
||||||
|
- Epic/Task: <추가/수정/완료/제거 요약>
|
||||||
|
|
||||||
|
## TODO 항목
|
||||||
|
|
||||||
|
- <확인이 필요한 항목> (해당 시)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- 로드맵 파일이 없는데 새 구조를 임의로 만들지 않는다. 이 경우 `create-roadmap`을 사용한다.
|
||||||
|
- evidence 없이 Phase, Milestone, Epic, Task를 `[완료]` 또는 `[검토중]`으로 처리하지 않는다.
|
||||||
|
- 전체 `ROADMAP.md`를 모든 작업의 필수 로딩 파일로 만들지 않는다.
|
||||||
|
- `ROADMAP.md`에 Milestone 상세 작업 체크리스트를 남기지 않는다.
|
||||||
|
- `current.md`에 개인별 현재 작업 위치나 완료 상태를 남기지 않는다.
|
||||||
|
- `current.md`에 `agent-ops/roadmap/archive/**` 경로를 남기지 않는다.
|
||||||
|
- archive 문서를 명시 요청 없이 읽거나 최신 템플릿으로 재포맷하지 않는다.
|
||||||
|
- 완료된 Phase/Milestone 기록을 삭제하지 않는다.
|
||||||
|
- Epic과 Task를 별도 파일로 분리하지 않는다.
|
||||||
|
- Phase와 Milestone 이름 또는 파일명에 순번을 강제하지 않는다.
|
||||||
|
- 사용자만 결정할 수 있는 항목이 남아 있는데 Milestone의 `구현 잠금`을 `해제`로 바꾸지 않는다.
|
||||||
|
- 사용자가 지정한 Phase/Milestone/Epic/Task anchor를 무시하지 않는다.
|
||||||
|
- 사용자가 명시하지 않은 기존 epic-id나 item-id를 바꾸지 않는다.
|
||||||
1
agent-task/.gitkeep
Normal file
1
agent-task/.gitkeep
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
|
||||||
1
agent-task/archive/.gitkeep
Normal file
1
agent-task/archive/.gitkeep
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
|
||||||
|
|
@ -1,17 +1,38 @@
|
||||||
# mattermost_push_plugin_example
|
# mattermost_push_plugin_example
|
||||||
|
|
||||||
Demonstrates how to use the mattermost_push_plugin plugin.
|
Thin Flutter app for exercising `mattermost_push_plugin` in isolation from any
|
||||||
|
real consuming product app.
|
||||||
|
|
||||||
## Getting Started
|
## Purpose
|
||||||
|
|
||||||
This project is a starting point for a Flutter application.
|
This app is the repository's integration test harness. Keep it small and focused
|
||||||
|
on the plugin contract:
|
||||||
|
|
||||||
A few resources to get you started if this is your first Flutter project:
|
- plugin registration in a real Flutter application
|
||||||
|
- method channel and event channel behavior
|
||||||
|
- notification-open routing callbacks
|
||||||
|
- Android manifest merge behavior
|
||||||
|
- manual smoke testing for Firebase FCM and Mattermost ACK flows
|
||||||
|
|
||||||
- [Learn Flutter](https://docs.flutter.dev/get-started/learn-flutter)
|
Product-specific UI, authentication, and navigation should stay in consuming
|
||||||
- [Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
apps. This app should only include the minimum surface needed to prove the
|
||||||
- [Flutter learning resources](https://docs.flutter.dev/reference/learning-resources)
|
plugin works independently.
|
||||||
|
|
||||||
For help getting started with Flutter development, view the
|
## Verification
|
||||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
|
||||||
samples, guidance on mobile development, and a full API reference.
|
Run these checks from this directory:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
flutter analyze
|
||||||
|
flutter test
|
||||||
|
flutter test integration_test
|
||||||
|
```
|
||||||
|
|
||||||
|
Run Android native unit tests from `example/android`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./gradlew testDebugUnitTest
|
||||||
|
```
|
||||||
|
|
||||||
|
Android Gradle tests require a configured Android SDK via `ANDROID_HOME` or
|
||||||
|
`example/android/local.properties`.
|
||||||
|
|
|
||||||
17
opencode.json
Normal file
17
opencode.json
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://opencode.ai/config.json",
|
||||||
|
"permission": {
|
||||||
|
"read": {
|
||||||
|
"agent-task/archive/**": "deny"
|
||||||
|
},
|
||||||
|
"glob": {
|
||||||
|
"agent-task/archive/**": "deny"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"watcher": {
|
||||||
|
"ignore": [
|
||||||
|
"agent-task/archive/**",
|
||||||
|
"agent-ops/roadmap/archive/**"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue