uctm 1.5.4 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +2 -2
- package/README.md +162 -284
- package/agents/builder.md +8 -16
- package/agents/committer.md +10 -23
- package/agents/orchestrator.md +228 -0
- package/agents/planner.md +8 -17
- package/agents/specifier.md +25 -43
- package/agents/verifier.md +3 -17
- package/lib/constants.mjs +1 -5
- package/lib/init.mjs +0 -18
- package/lib/update.mjs +1 -1
- package/package.json +2 -6
- package/references/agent-flow.md +121 -121
- package/references/context-policy.md +4 -2
- package/references/file-content-schema.md +38 -18
- package/references/shared-prompt-sections.md +23 -15
- package/references/work-activity-log.md +21 -14
- package/references/xml-schema.md +102 -5
- package/skills/sdd-pipeline/SKILL.md +1 -1
- package/skills/uctm-init/SKILL.md +1 -2
- package/skills/work-pipeline/SKILL.md +23 -22
- package/.agent/router_rule_config.json +0 -47
- package/agents/scheduler.md +0 -152
- package/references/callback-protocol.md +0 -40
- package/skills/init/SKILL.md +0 -95
package/lib/update.mjs
CHANGED
|
@@ -44,5 +44,5 @@ export function update(isGlobal) {
|
|
|
44
44
|
console.log(`\n Updating ${dim(label)} ...`);
|
|
45
45
|
console.log(` ${green('✓')} ${agentCount} agent files updated`);
|
|
46
46
|
console.log(` ${green('✓')} ${refCount} reference files updated`);
|
|
47
|
-
console.log(` ${dim('-')} CLAUDE.md
|
|
47
|
+
console.log(` ${dim('-')} CLAUDE.md untouched\n`);
|
|
48
48
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uctm",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Universal Claude Task Manager — SDD-based task pipeline subagent system for Claude Code CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
"lib/",
|
|
12
12
|
"agents/",
|
|
13
13
|
"references/",
|
|
14
|
-
".agent/",
|
|
15
14
|
".claude-plugin/",
|
|
16
15
|
"skills/"
|
|
17
16
|
],
|
|
@@ -34,8 +33,5 @@
|
|
|
34
33
|
"type": "git",
|
|
35
34
|
"url": "git+https://github.com/UCJung/uc-taskmanager-claude-agent.git"
|
|
36
35
|
},
|
|
37
|
-
"homepage": "https://github.com/UCJung/uc-taskmanager-claude-agent#readme"
|
|
38
|
-
"dependencies": {
|
|
39
|
-
"uctm": "^1.5.0"
|
|
40
|
-
}
|
|
36
|
+
"homepage": "https://github.com/UCJung/uc-taskmanager-claude-agent#readme"
|
|
41
37
|
}
|
package/references/agent-flow.md
CHANGED
|
@@ -1,179 +1,179 @@
|
|
|
1
1
|
# Agent Flow — Main Claude 역할 가이드
|
|
2
2
|
|
|
3
|
-
> Main Claude는
|
|
4
|
-
>
|
|
5
|
-
>
|
|
6
|
-
> 다음 Agent를 실행할때 반환값을 전달하세요.
|
|
3
|
+
> Main Claude는 **트리거와 게이트 경계**만 담당합니다.
|
|
4
|
+
> 파이프라인 내부 진행(WORK 생성 → 설계 → TASK 실행 → 완료)은 **orchestrator**가 전담합니다.
|
|
5
|
+
> Main Claude는 orchestrator 외의 다른 에이전트를 **직접 spawn하지 않습니다**.
|
|
7
6
|
|
|
8
7
|
---
|
|
9
8
|
|
|
10
|
-
##
|
|
9
|
+
## 1. Main Claude 역할 (트리거 + 게이트 경계)
|
|
11
10
|
|
|
12
|
-
Main Claude
|
|
13
|
-
당신의 역할은 흐름에 따라 실행하는 것이지
|
|
11
|
+
Main Claude가 직접 수행하는 일은 다음 4가지뿐입니다.
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
1. **트리거 감지** — `[tag]` 메시지 또는 WORK 재개 요청(예: "WORK-01 계속실행", "resume WORK-01")을 감지.
|
|
14
|
+
2. **orchestrator 1회 spawn** — 다음을 전달:
|
|
15
|
+
- `REFERENCES_DIR={절대 경로}`
|
|
16
|
+
- `mode=gated|auto` — 사용자 메시지에 "auto"/"자동으로"가 포함되면 `auto`, 그 외는 기본값 `gated`
|
|
17
|
+
- 사용자 요청 원문 (재개 요청이면 대상 `WORK_ID`)
|
|
18
|
+
- spawn 결과로 받는 **agentId를 보관**한다(재개 시 name이 아니라 **agentId**로 지정 — 이름 재사용 오배달 방지).
|
|
19
|
+
3. **게이트 처리** — orchestrator가 `<gate type="stage">` 또는 `<gate type="decision">`을 반환하고 **yield(파킹)** 하면:
|
|
20
|
+
1. 게이트 내용을 사용자에게 그대로 제시한다 — `type="stage"`는 완료 요약, `type="decision"`은 배경(`<context>`) + 선택지(`<options>`) + 권고안(`<recommended>`)(`AskUserQuestion` 등으로 선택 요청).
|
|
21
|
+
2. 사용자의 승인 또는 선택을 기다린다.
|
|
22
|
+
3. 응답을 받으면 **`SendMessage(agentId, 결정내용)`으로 컨텍스트를 유지한 채 재개**한다.
|
|
23
|
+
4. `SendMessage`가 실패하면(파킹 핸들 유실 등) **폴백**: `works/{WORK_ID}/work_{WORK_ID}.log` + `DECISIONS.md`를 근거로 orchestrator를 `WORK_ID`와 함께 새로 spawn해 재개시킨다.
|
|
24
|
+
4. **완료 처리** — orchestrator가 최종 WORK 요약을 반환하면 사용자에게 그대로 릴레이하고 **`TaskStop(agentId)`로 파킹 핸들을 해제**한다.
|
|
16
25
|
|
|
17
|
-
|
|
18
|
-
[] 태그 감지 → specifier 호출
|
|
19
|
-
│
|
|
20
|
-
specifier 실행 mode 판단
|
|
21
|
-
│
|
|
22
|
-
├─ direct mode → specifier 수행 → planner 역할 수행
|
|
23
|
-
│
|
|
24
|
-
└─ pipeline/full → specifier 수행 → planner dispatch XML 반환
|
|
25
|
-
|
|
26
|
-
```
|
|
26
|
+
`mode=auto`인 경우 orchestrator가 게이트/의사결정 정지 없이 1회 spawn으로 완주하므로, 3단계(게이트 처리)는 발생하지 않는다 — Main Claude는 spawn 후 최종 결과만 수신·릴레이하고 `TaskStop`으로 마무리한다.
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
30
|
-
##
|
|
30
|
+
## 2. Orchestrator 내부 흐름
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
1. specifier 호출 → planner 역할 수행 + builder dispatch XML 반환
|
|
34
|
-
2. ⛔ 정지 — 요약을 사용자에게 제시하고 승인 대기
|
|
35
|
-
3. builder 호출
|
|
36
|
-
4. verifier 호출
|
|
37
|
-
5. committer 호출
|
|
38
|
-
```
|
|
32
|
+
Main Claude가 관여하지 않는 orchestrator 내부 진행이다. 상세 절차와 로그 규칙은 `develop/agents/orchestrator.md`를 정본으로 하며, 아래는 Main Claude가 게이트 신호를 올바르게 해석하기 위한 요약이다.
|
|
39
33
|
|
|
40
|
-
|
|
34
|
+
### STEP A. Specifier spawn (WORK 생성)
|
|
41
35
|
|
|
42
|
-
|
|
36
|
+
- orchestrator가 specifier를 중첩 spawn → `Requirement.md` + WORK 폴더 생성, 복잡도 판정(단순/복잡).
|
|
37
|
+
- `mode=gated`: 활동 로그에 `GATE_WAIT — stage=specifier` 기록 → `<gate type="stage" work="{WORK}" stage="specifier">` 반환 후 **yield**.
|
|
38
|
+
- `mode=auto`: 게이트 생략, `STAGE_DONE — stage=specifier` 즉시 기록 후 STEP B로 진행.
|
|
43
39
|
|
|
44
|
-
|
|
45
|
-
1. specifier 호출
|
|
46
|
-
2. planner 호출
|
|
47
|
-
3. ⛔ 정지 — Requirement.md + PLAN.md + TASK 목록을 제시하고 승인 대기
|
|
48
|
-
4. 각 TASK에 대해 (오름차순):
|
|
49
|
-
a. builder 호출 TASK별
|
|
50
|
-
b. verifier 호출 TASK별
|
|
51
|
-
c. committer 호출 TASK별
|
|
52
|
-
d. 미완료 TASK가 남아있으면 다음 TASK로 계속
|
|
53
|
-
```
|
|
40
|
+
### STEP B. Planner spawn
|
|
54
41
|
|
|
55
|
-
|
|
42
|
+
- planner를 중첩 spawn → `PLAN.md` + TASK DAG 생성.
|
|
43
|
+
- `mode=gated`: `GATE_WAIT — stage=planner` 기록 → `<gate type="stage" work="{WORK}" stage="planner">` 반환 후 **yield**.
|
|
44
|
+
- `mode=auto`: 게이트 생략, `STAGE_DONE — stage=planner` 즉시 기록 후 STEP C로 진행.
|
|
56
45
|
|
|
57
|
-
|
|
46
|
+
### STEP C. TASK DAG 실행 — 게이트 없음
|
|
58
47
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
2
|
|
62
|
-
3. ⛔ 정지 — Requirement.md + PLAN.md + TASK 목록을 제시하고 승인 대기
|
|
63
|
-
4. scheduler 호출
|
|
64
|
-
5. builder 호출
|
|
65
|
-
6. verifier 호출
|
|
66
|
-
7. committer 호출
|
|
67
|
-
8. 미완료 TASK가 남아있으면 4.scheduler 호출
|
|
68
|
-
```
|
|
48
|
+
- `work_{WORK}.log` + `PLAN.md`로 DAG를 해석해 READY TASK를 오름차순으로 판정한다. 복수 READY면 builder를 병렬로 중첩 spawn한다.
|
|
49
|
+
- TASK별로 builder → verifier → committer를 순차 spawn한다. 이 단계는 사용자 승인 대상이 아니므로 고정 게이트가 없다.
|
|
50
|
+
- verifier/committer가 FAIL을 반환하면 builder에 최대 2회 재디스패치(총 3회 시도)한다. 3회 모두 실패하면 자식이 `<needs-decision>`으로 orchestrator에 상향하고, `mode=gated`면 게이트로 승격, `mode=auto`면 권고안 자동결정 후 계속한다.
|
|
69
51
|
|
|
70
|
-
|
|
52
|
+
### STEP D. 로그 일괄 기록
|
|
71
53
|
|
|
72
|
-
|
|
54
|
+
- 활동 로그를 기록하는 주체는 **orchestrator뿐**이다.
|
|
55
|
+
- 이벤트 순서: `ORCHESTRATOR_START` → (`STAGE_START` → [`GATE_WAIT`/`DECISION_WAIT` → `DECISION`] → `STAGE_DONE`)를 단계마다 반복 → `ORCHESTRATOR_DONE`.
|
|
73
56
|
|
|
74
|
-
|
|
57
|
+
### 재개 규칙 (마지막 로그 이벤트 기준)
|
|
75
58
|
|
|
76
|
-
|
|
59
|
+
| 마지막 로그 이벤트 | 판정 | 처리 |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| 로그 없음 | 신규 WORK | STEP A부터 시작 |
|
|
62
|
+
| `{STAGE}_START`만 있고 대응하는 `STAGE_DONE`/`GATE_WAIT`/`DECISION_WAIT` 없음 | 자식 실행 중 중단됨 | 자식 재실행 |
|
|
63
|
+
| `GATE_WAIT — stage=X` | 게이트 미승인 | 자식 재실행 없이 디스크 산출물 재사용, **동일 게이트를 재제시** |
|
|
64
|
+
| `DECISION_WAIT — stage=X` | 결정 미확정 | `DECISIONS.md`의 `상태: PENDING` 항목을 동일 배경/선택지/권고안으로 재제시 |
|
|
65
|
+
| `DECISION — ... by=...` | 결정 확정, 후속 `STAGE_DONE` 없음 | 결정을 반영해 해당 단계 이어서 진행 |
|
|
66
|
+
| `STAGE_DONE — stage=X` | 해당 단계 완료(게이트 통과됨) | 다음 단계로 진행 |
|
|
67
|
+
| `ORCHESTRATOR_DONE` | WORK 이미 완료 | 재개 불필요 — 완료 상태 보고 |
|
|
77
68
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
- PLANNER_START → 중단됨, planner 재수행
|
|
90
|
-
- SPECIFIER_DONE → specifier 완료, planner 호출
|
|
91
|
-
- SPECIFIER_START → 중단됨, specifier 재수행
|
|
92
|
-
- 로그 파일 없음 → 처음부터 시작
|
|
93
|
-
|
|
94
|
-
2. 남은 각 TASK에 대해:
|
|
95
|
-
a. builder 호출 → 구현
|
|
96
|
-
b. verifier 호출 → 검증
|
|
97
|
-
c. committer 호출 → 커밋
|
|
98
|
-
```
|
|
69
|
+
> **핵심 불변식**: `STAGE_DONE`은 게이트가 있는 단계에서는 게이트가 해소(RESOLVED)된 이후에만 기록된다. 따라서 **미승인 게이트는 로그에 `STAGE_DONE`이 남지 않아 재개 시 절대 스킵되지 않는다.**
|
|
70
|
+
|
|
71
|
+
### 슬라이딩 윈도우 (컨텍스트 핸드오프)
|
|
72
|
+
|
|
73
|
+
orchestrator가 자식 프롬프트를 구성할 때 이전 단계 결과를 다음 기준으로 압축해 전달한다.
|
|
74
|
+
|
|
75
|
+
| 단계 거리 | 상세 레벨 | 포함 필드 |
|
|
76
|
+
|---|---|---|
|
|
77
|
+
| 직전 (1단계) | `FULL` | what + why + caution + incomplete |
|
|
78
|
+
| 2단계 전 | `SUMMARY` | what만 (1-3줄) |
|
|
79
|
+
| 3단계+ | `DROP` | 전달하지 않음 |
|
|
99
80
|
|
|
100
81
|
---
|
|
101
82
|
|
|
102
|
-
##
|
|
83
|
+
## 3. 승인 게이트 (CRITICAL)
|
|
103
84
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
85
|
+
게이트는 orchestrator가 자율 실행을 멈추고 반환하는 정지 신호다. 중첩 sub-agent는 사용자에게 직접 질문할 수 없으므로, **승인/결정의 실제 처리(사용자에게 묻고 응답을 받는 것)는 항상 Main Claude 경계에서 이뤄진다.**
|
|
86
|
+
|
|
87
|
+
> **반드시 정지하고 명시적 사용자 승인/결정을 기다려야 합니다.**
|
|
88
|
+
> 유일한 예외는 auto 모드 — 사용자의 원본 메시지에 "auto" 또는 "자동으로"가 포함된 경우뿐이다.
|
|
89
|
+
|
|
90
|
+
게이트는 두 종류이며 Main Claude의 처리 방식은 동일하다(§1-3 참조).
|
|
91
|
+
|
|
92
|
+
### 고정 게이트 (2개, `type="stage"`)
|
|
93
|
+
|
|
94
|
+
| 게이트 | 발생 지점 | `stage` 값 | 승인 후 다음 |
|
|
95
|
+
|---|---|---|---|
|
|
96
|
+
| GATE-1 | specifier 완료 후 | `specifier` | planner spawn |
|
|
97
|
+
| GATE-2 | planner 완료 후 | `planner` | STEP C(builder) |
|
|
98
|
+
|
|
99
|
+
### 동적 게이트 (`type="decision"`)
|
|
100
|
+
|
|
101
|
+
- 고정 게이트 사이 **어느 단계에서든**(설계·구현·검증 포함) orchestrator 또는 자식이 사용자 결정이 필요하다고 판단하면 즉시 발생한다.
|
|
102
|
+
- 판단 기준 예: 요구 해석의 다의성, 설계 트레이드오프, 명시된 범위 초과, 파괴적/비가역적 변경, 재시도 3회 실패.
|
|
103
|
+
- 자식은 `<needs-decision>`으로 orchestrator에 먼저 상향하며, orchestrator가 자동 결정 가능 여부를 판단한 뒤 불가능하면 `<gate type="decision">`으로 승격해 Main Claude에 전달한다.
|
|
104
|
+
- `<gate type="decision">`은 `<context>`(배경)·`<options>`(선택지)·`<recommended>`(권고안)를 반드시 포함한다.
|
|
105
|
+
|
|
106
|
+
### auto 모드
|
|
107
|
+
|
|
108
|
+
| 모드 | 정지 횟수 | 처리 |
|
|
109
|
+
|---|:---:|---|
|
|
110
|
+
| gated (기본값) | 고정 게이트 1~2회 + 동적 게이트 발생 시마다 | Main Claude가 매번 승인/선택 후 재개 |
|
|
111
|
+
| auto ("auto"/"자동으로") | 0 | orchestrator 1회 spawn으로 완주. 모든 판단 지점은 권고안으로 자동결정되어 최종 보고서 `## 자동 결정 사항`과 `DECISIONS.md`에 기록 |
|
|
112
|
+
|
|
113
|
+
### 승인 요청 방법 (Main Claude)
|
|
114
|
+
|
|
115
|
+
1. `<gate>` 내용을 그대로 사용자에게 제시(요약 또는 배경+선택지+권고안).
|
|
116
|
+
2. "진행할까요?" 또는 동등한 질문(`type="decision"`이면 선택 요청).
|
|
117
|
+
3. **사용자 응답 대기** — 응답 전까지 `SendMessage`로 재개하지 말 것.
|
|
112
118
|
|
|
113
119
|
---
|
|
114
120
|
|
|
115
|
-
##
|
|
121
|
+
## 4. 모드/스폰 수
|
|
116
122
|
|
|
117
|
-
|
|
|
118
|
-
|
|
119
|
-
|
|
|
120
|
-
|
|
121
|
-
|
|
123
|
+
| Main → Orchestrator | Orchestrator → Specifier | → Planner | → Builder | → Verifier | → Committer | 합계 |
|
|
124
|
+
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
|
125
|
+
| 1 | 1 | 1 | N | N | N | **3 + 3N** |
|
|
126
|
+
|
|
127
|
+
- `gated`/`auto` 여부는 spawn 수에 영향을 주지 않는다 — 게이트 정지 발생 여부만 다르다(§3).
|
|
128
|
+
- 위 표는 orchestrator 내부 자식 spawn만 집계한다. Main Claude가 spawn하는 대상은 오직 orchestrator 1개다.
|
|
122
129
|
|
|
123
130
|
---
|
|
124
131
|
|
|
125
|
-
##
|
|
132
|
+
## 5. 기존 WORK 재개
|
|
133
|
+
|
|
134
|
+
Main Claude는 재개 요청을 감지하면 대상 `WORK_ID`를 orchestrator에 전달하는 것으로 끝난다. 재개 지점 판정(§2 "재개 규칙")은 orchestrator가 로그를 읽어 스스로 수행한다.
|
|
126
135
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
136
|
+
1. 파킹된 agentId를 보관하고 있으면 → `SendMessage(agentId, "WORK-{NN} 계속")`으로 컨텍스트를 유지한 채 재개.
|
|
137
|
+
2. 세션이 끊겨 핸들이 없으면(예: 새 세션에서 "WORK-01 계속실행") → orchestrator를 `WORK_ID` + `REFERENCES_DIR` + (승계된) `mode`와 함께 새로 spawn → orchestrator가 `work_{WORK_ID}.log`의 마지막 이벤트로 재개 지점을 판정한다.
|
|
138
|
+
3. 단순/복잡 분기는 다시 묻지 않는다 — orchestrator가 `PLAN.md`와 TASK 구성에서 판정한다.
|
|
130
139
|
|
|
131
|
-
|
|
132
|
-
|------|:---------:|------|------------------------|
|
|
133
|
-
| direct | 1 | Specifier 완료 및 Planner 역할 수행 완료 후 | Requirement.md + PLAN.md + TASK-00.md 요약 |
|
|
134
|
-
| pipeline/full | 2 | Specifier 완료 후, Planner 완료 후 | Requirement.md 요약, PLAN.md + TASK-00.md 요약|
|
|
135
|
-
| auto-approve | 0 | — | 모든 승인 게이트 생략 |
|
|
140
|
+
---
|
|
136
141
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
142
|
+
## 6. 에이전트 역할 요약
|
|
143
|
+
|
|
144
|
+
| 에이전트 | 역할 | 모델 |
|
|
145
|
+
|---|---|---|
|
|
146
|
+
| orchestrator | 파이프라인 전체 조정 + TASK DAG 스케줄링 + 게이트/의사결정 중재 + 로그 일괄 기록 | opus |
|
|
147
|
+
| specifier | 요구사항 분석 | opus |
|
|
148
|
+
| planner | 실행계획 수립 + TASK 분해 | opus |
|
|
149
|
+
| builder | 코드 구현 | sonnet |
|
|
150
|
+
| verifier | 빌드/린트/테스트 검증 | haiku |
|
|
151
|
+
| committer | 결과 보고서 + git commit | haiku |
|
|
141
152
|
|
|
142
153
|
---
|
|
143
154
|
|
|
144
155
|
## References Directory 전달 (필수)
|
|
145
156
|
|
|
146
|
-
Main Claude는
|
|
147
|
-
설치 방법(npm 또는 plugin)에 관계없이
|
|
157
|
+
Main Claude는 orchestrator spawn 시(신규/재개 모두) references 디렉토리 경로를 전달해야 합니다.
|
|
158
|
+
설치 방법(npm 또는 plugin)에 관계없이 orchestrator와 그 자식이 레퍼런스 파일을 찾을 수 있도록 합니다.
|
|
148
159
|
|
|
149
160
|
**전달 방법:**
|
|
150
|
-
-
|
|
161
|
+
- orchestrator spawn 프롬프트 상단에 `REFERENCES_DIR={absolute_path}` 추가
|
|
151
162
|
- npm 설치: `.claude/references` 사용 (프로젝트 루트 기준 기본값)
|
|
152
163
|
- plugin 설치: 스킬의 "Base directory"에서 유도 (`{base_dir}/../../references`)
|
|
153
164
|
|
|
154
165
|
**예시:**
|
|
155
166
|
```
|
|
156
167
|
REFERENCES_DIR=C:/Users/me/.claude/plugins/cache/uc-taskmanager/abc123/references
|
|
168
|
+
mode=gated
|
|
157
169
|
|
|
158
|
-
|
|
159
|
-
...
|
|
160
|
-
</dispatch>
|
|
170
|
+
[WORK] 사용자 요청 원문...
|
|
161
171
|
```
|
|
162
172
|
|
|
163
|
-
REFERENCES_DIR를 사용할 수 없는 경우
|
|
164
|
-
|
|
165
|
-
---
|
|
166
|
-
|
|
167
|
-
## Context Handoff (슬라이딩 윈도우)
|
|
168
|
-
|
|
169
|
-
| 거리 | 레벨 | 내용 |
|
|
170
|
-
|------|------|------|
|
|
171
|
-
| 직전 | FULL | what + why + caution + incomplete |
|
|
172
|
-
| 2단계 전 | SUMMARY | what 1-2줄 |
|
|
173
|
-
| 3단계+ | DROP | 전달하지 않음 |
|
|
173
|
+
REFERENCES_DIR를 사용할 수 없는 경우(예: plugin 없는 npm 설치), orchestrator는 `.claude/references/`를 폴백으로 사용합니다. orchestrator는 자신이 읽은 레퍼런스 내용을 `<ref-cache>`(`xml-schema.md` § 4)로 자식에게 재전달할 수 있습니다.
|
|
174
174
|
|
|
175
175
|
---
|
|
176
176
|
|
|
177
177
|
## 레퍼런스 로딩
|
|
178
178
|
|
|
179
|
-
|
|
179
|
+
Main Claude는 레퍼런스 파일을 읽지 않으며 — `agent-flow.md`만 읽습니다. orchestrator와 그 자식들이 `{REFERENCES_DIR}/`에서 각자(또는 ref-cache로 전달받아) 필요한 레퍼런스 파일을 읽습니다.
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
1. builder 성공 여부 확인 (context-handoff 상태 확인)
|
|
56
56
|
2. result.md 작성 + git commit
|
|
57
57
|
|
|
58
|
-
출력: → `{REFERENCES_DIR}/file-content-schema.md` §
|
|
58
|
+
출력: → `{REFERENCES_DIR}/file-content-schema.md` § 3 참조
|
|
59
59
|
|
|
60
60
|
## TASK 간 의존성 전달
|
|
61
61
|
|
|
@@ -63,7 +63,9 @@
|
|
|
63
63
|
- 2단계 전: **SUMMARY** (what만)
|
|
64
64
|
- 3단계+: **DROP**
|
|
65
65
|
|
|
66
|
-
##
|
|
66
|
+
## Orchestrator 디스패치
|
|
67
|
+
|
|
68
|
+
TASK DAG 실행 중 다음 자식(중첩 spawn)의 프롬프트를 구성하는 주체는 **orchestrator**다 — dispatch XML을 만들어 자식 spawn 프롬프트에 포함한다.
|
|
67
69
|
|
|
68
70
|
```xml
|
|
69
71
|
<!-- Verifier: Builder FULL -->
|
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
| 생성 파일 | 참조 섹션 | 위반 시 결과 |
|
|
8
8
|
|-----------|----------|-------------|
|
|
9
9
|
| `Requirement.md` | § 0 | |
|
|
10
|
-
| `PLAN.md` | § 1 | `parsePlanMd()` 파싱 실패,
|
|
10
|
+
| `PLAN.md` | § 1 | `parsePlanMd()` 파싱 실패, orchestrator 파이프라인 작동 불가 |
|
|
11
11
|
| `TASK-XX.md` | § 2 | `parseTaskFilename()` DB 등록 누락 |
|
|
12
12
|
| `TASK-XX_result.md` | § 3 | context-handoff 누락 |
|
|
13
|
-
| `
|
|
13
|
+
| `DECISIONS.md` | § 4 | 재개(resume) 시 PENDING 결정 재제시 불가 |
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
@@ -50,7 +50,6 @@
|
|
|
50
50
|
|
|
51
51
|
> Created: {YYYY-MM-DD}
|
|
52
52
|
> Requirement: {REQ-XXX | 사용자 요청 텍스트}
|
|
53
|
-
> Execution-Mode: {direct | pipeline | full}
|
|
54
53
|
> Project: {프로젝트 이름}
|
|
55
54
|
> Tech Stack: {스택}
|
|
56
55
|
> Language: {lang_code}
|
|
@@ -178,7 +177,7 @@
|
|
|
178
177
|
|
|
179
178
|
---
|
|
180
179
|
|
|
181
|
-
## § 3. TASK-XX_result.md
|
|
180
|
+
## § 3. TASK-XX_result.md
|
|
182
181
|
|
|
183
182
|
경로: `works/{WORK_ID}/TASK-XX_result.md`
|
|
184
183
|
|
|
@@ -231,27 +230,47 @@ None
|
|
|
231
230
|
|
|
232
231
|
---
|
|
233
232
|
|
|
234
|
-
## § 4.
|
|
233
|
+
## § 4. DECISIONS.md
|
|
234
|
+
|
|
235
|
+
경로: `works/{WORK_ID}/DECISIONS.md`
|
|
236
|
+
|
|
237
|
+
orchestrator가 `<gate type="decision">` 또는 자식 에이전트의 `<needs-decision>`(→ `xml-schema.md` § 5, § 6)을 수신할 때마다 항목을 추가하는 결정 로그. 게이트가 yield된 시점에는 항목을 **PENDING**으로 먼저 기록하고, 승인/자동결정으로 해소되면 같은 항목을 **RESOLVED**로 갱신한다.
|
|
235
238
|
|
|
236
239
|
```markdown
|
|
237
|
-
#
|
|
240
|
+
# DECISIONS — WORK-NN
|
|
238
241
|
|
|
239
|
-
|
|
240
|
-
>
|
|
241
|
-
>
|
|
242
|
-
>
|
|
242
|
+
## D-01
|
|
243
|
+
> 시각: {YYYY-MM-DDTHH:MM:SSZ}
|
|
244
|
+
> 단계: {specifier|planner|builder|verifier|committer}
|
|
245
|
+
> 상태: {PENDING|RESOLVED}
|
|
246
|
+
|
|
247
|
+
### 배경
|
|
248
|
+
{결정이 필요한 이유}
|
|
243
249
|
|
|
244
|
-
|
|
245
|
-
{1
|
|
250
|
+
### 선택지
|
|
251
|
+
1. {선택지 1}
|
|
252
|
+
2. {선택지 2}
|
|
246
253
|
|
|
247
|
-
|
|
248
|
-
|
|
254
|
+
### 권고안
|
|
255
|
+
{orchestrator/자식 에이전트가 제시한 권고}
|
|
249
256
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
257
|
+
### 확정값
|
|
258
|
+
{확정된 선택 — PENDING 상태에서는 공란 또는 "(대기 중)"}
|
|
259
|
+
|
|
260
|
+
### 결정주체
|
|
261
|
+
{user 승인 | auto}
|
|
253
262
|
```
|
|
254
263
|
|
|
264
|
+
| 필드 | PENDING (게이트 yield 시) | RESOLVED (해소 후) |
|
|
265
|
+
|------|---------------------------|---------------------|
|
|
266
|
+
| 확정값 | 공란 / `(대기 중)` | 채움 |
|
|
267
|
+
| 결정주체 | 공란 | `user 승인` 또는 `auto` |
|
|
268
|
+
|
|
269
|
+
- **재개(resume) 근거**: orchestrator가 중단 후 재개할 때 DECISIONS.md에서 `상태: PENDING` 항목을 찾아 동일한 배경·선택지·권고안으로 게이트를 다시 제시한다. 이 상태 필드가 없으면 재개 시 이미 물었던 결정인지 판단할 수 없어, 미승인 결정을 건너뛰거나 사용자에게 같은 질문을 중복 제시하는 오류가 발생한다.
|
|
270
|
+
- 활동 로그의 `DECISION_WAIT`/`DECISION` 이벤트와 1:1로 대응한다 → `work-activity-log.md` 참조.
|
|
271
|
+
|
|
272
|
+
생성 주체: orchestrator
|
|
273
|
+
|
|
255
274
|
---
|
|
256
275
|
|
|
257
276
|
## § 5. 파일 이름 규칙
|
|
@@ -262,6 +281,7 @@ None
|
|
|
262
281
|
| WORK 계획 | `PLAN.md` | planner / specifier |
|
|
263
282
|
| TASK 계획 | `TASK-NN.md` | planner / specifier |
|
|
264
283
|
| TASK 결과 | `TASK-NN_result.md` | committer |
|
|
265
|
-
|
|
|
284
|
+
| 결정 로그 | `DECISIONS.md` | orchestrator |
|
|
285
|
+
| 활동 로그 | `work_WORK-NN.log` | orchestrator (추가) |
|
|
266
286
|
|
|
267
287
|
`WORK-NN-TASK-NN.md` 형식 금지 → `parseTaskFilename()`이 인식할 수 없음.
|
|
@@ -71,29 +71,26 @@ works/{WORK_ID}/
|
|
|
71
71
|
# Glob 도구 사용: pattern "works/WORK-*/" → 모든 WORK 디렉토리 목록 (정렬)
|
|
72
72
|
# 각 WORK (내림차순)에 대해 works/WORK-NN/work_WORK-NN.log 마지막 줄 읽기
|
|
73
73
|
# - 로그 파일 없음 → 시작 안 됨
|
|
74
|
-
# - 마지막
|
|
74
|
+
# - 마지막 줄이 "ORCHESTRATOR_DONE" → 완료됨
|
|
75
75
|
# 완전히 완료되지 않은 첫 번째 WORK가 활성 WORK
|
|
76
76
|
|
|
77
77
|
# 모든 WORK 목록
|
|
78
78
|
# Glob 도구 사용: pattern "works/WORK-*/"
|
|
79
79
|
|
|
80
|
-
# 활동 로그의 마지막 줄로 WORK/TASK 상태 파악
|
|
80
|
+
# 활동 로그의 마지막 줄로 WORK/TASK 상태 파악 (orchestrator가 일괄 기록 → work-activity-log.md 참조)
|
|
81
81
|
# works/${WORK_ID}/work_${WORK_ID}.log 마지막 줄 읽기
|
|
82
82
|
# 형식: [timestamp] EVENT — description
|
|
83
83
|
#
|
|
84
|
-
# 핵심 규칙:
|
|
84
|
+
# 핵심 규칙: STAGE_START에 대응하는 STAGE_DONE/GATE_WAIT/DECISION_WAIT가 없으면 = 자식 실행 중 중단됨, 해당 단계 재수행 필요
|
|
85
85
|
#
|
|
86
|
-
#
|
|
87
|
-
#
|
|
88
|
-
#
|
|
89
|
-
#
|
|
90
|
-
#
|
|
91
|
-
#
|
|
92
|
-
#
|
|
93
|
-
#
|
|
94
|
-
# SPECIFIER_DONE → specifier 완료, planner 필요
|
|
95
|
-
# SPECIFIER_START → specifier 중단됨, specifier 재수행
|
|
96
|
-
# 로그 파일 없음 → 처음부터 시작
|
|
86
|
+
# ORCHESTRATOR_DONE → WORK 전체 완료
|
|
87
|
+
# STAGE_DONE — stage=X[ task=TASK-NN] → 해당 단계 완료(게이트 통과됨), 다음 단계로
|
|
88
|
+
# GATE_WAIT — stage=X → 게이트 미승인, 자식 재실행 없이 동일 게이트 재제시
|
|
89
|
+
# DECISION_WAIT — stage=X[ task=TASK-NN] → 결정 미확정, DECISIONS.md의 PENDING 항목 재제시
|
|
90
|
+
# DECISION — stage=X by=user|auto → 결정 확정됨, 후속 STAGE_DONE 없으면 해당 단계 이어서 진행
|
|
91
|
+
# STAGE_START — stage=X[ task=TASK-NN] → (대응 DONE/WAIT 없으면) 자식 실행 중 중단됨, 재실행
|
|
92
|
+
# ORCHESTRATOR_START → orchestrator 시작됨, 하위 이벤트로 세부 판정
|
|
93
|
+
# 로그 파일 없음 → 처음부터 시작 (신규 WORK)
|
|
97
94
|
```
|
|
98
95
|
|
|
99
96
|
---
|
|
@@ -115,6 +112,18 @@ works/{WORK_ID}/
|
|
|
115
112
|
|
|
116
113
|
---
|
|
117
114
|
|
|
115
|
+
## § 6. 자동결정 기록 관례
|
|
116
|
+
|
|
117
|
+
권고안을 자동결정(결정주체 `auto`)한 경우, 판단 근거를 남겨 추적 가능하게 한다.
|
|
118
|
+
|
|
119
|
+
- **기록 위치**: `works/{WORK_ID}/DECISIONS.md`(항목별 배경/선택지/권고안/확정값/결정주체/상태) + 최종 결과보고서 `## 자동 결정 사항` 목록.
|
|
120
|
+
- **기록 시점**: 결정 확정 즉시 `RESOLVED`로 기록. `mode=auto`뿐 아니라 `mode=gated`에서 orchestrator가 경미한 사항으로 판단해 게이트 없이 자체 확정(`by=auto`)한 경우도 동일하게 기록.
|
|
121
|
+
- **최소 기재 항목**: 대상(stage 또는 task) · 확정값 · 근거 1줄.
|
|
122
|
+
|
|
123
|
+
→ 상세 포맷: `file-content-schema.md` § 4 참조. 기록 주체·이벤트: `work-activity-log.md`의 `DECISION` 이벤트 참조.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
118
127
|
## § 7. PLAN.md 필수 메타 정보 — 7개 필드
|
|
119
128
|
|
|
120
129
|
→ `{REFERENCES_DIR}/file-content-schema.md` § 1 참조
|
|
@@ -123,7 +132,6 @@ works/{WORK_ID}/
|
|
|
123
132
|
|------|------|------|
|
|
124
133
|
| `> Created:` | ✅ | YYYY-MM-DD |
|
|
125
134
|
| `> Requirement:` | ✅ | `REQ-XXX` 또는 사용자 요청 텍스트 |
|
|
126
|
-
| `> Execution-Mode:` | ✅ | `direct` / `pipeline` / `full` |
|
|
127
135
|
| `> Project:` | ✅ | 프로젝트 이름 |
|
|
128
136
|
| `> Tech Stack:` | ✅ | 감지된 기술 스택 |
|
|
129
137
|
| `> Language:` | ✅ | 언어 코드 (`ko`, `en` 등) |
|
|
@@ -1,26 +1,33 @@
|
|
|
1
1
|
# 작업 활동 로그
|
|
2
2
|
|
|
3
|
-
`works/{WORK_ID}/work_{WORK_ID}.log`에
|
|
3
|
+
`works/{WORK_ID}/work_{WORK_ID}.log`에 실행 이벤트를 기록.
|
|
4
4
|
|
|
5
5
|
## 규칙
|
|
6
6
|
|
|
7
|
-
1.
|
|
8
|
-
2.
|
|
9
|
-
3.
|
|
7
|
+
1. **기록 주체**: **orchestrator**. 자식의 spawn/완료를 `STAGE_START`/`STAGE_DONE`으로 기록한다.
|
|
8
|
+
2. **타임스탬프**: Bash로 `date -u +"%Y-%m-%dT%H:%M:%SZ"` 실행하여 실제 UTC 시간 획득. 더미 값 사용 금지.
|
|
9
|
+
3. **기록 방법**: Bash `echo` 로 추가.
|
|
10
|
+
4. **`STAGE_DONE`은 게이트 통과 후에 기록한다.** 해당 단계에 게이트(`<gate type="stage">` 또는 `<gate type="decision">`)가 있는 경우, Main Claude/사용자의 승인·결정으로 게이트가 해소(RESOLVED)된 시점에만 `STAGE_DONE`을 남긴다. 게이트 대기 중에는 `GATE_WAIT`/`DECISION_WAIT`만 기록되고, `STAGE_DONE`은 아직 기록되지 않은 상태로 남는다.
|
|
11
|
+
- **근거(재개 판정)**: 파이프라인이 중단 후 재개(resume)될 때 orchestrator는 로그의 마지막 이벤트로 재개 지점을 판정한다. 특정 단계에 `STAGE_START`만 있고 `STAGE_DONE`이 없다면 "그 단계의 게이트가 아직 승인/결정되지 않았다"는 뜻이므로, orchestrator는 다음 단계로 건너뛰지 않고 동일 게이트를 다시 제시해야 한다. `STAGE_DONE`을 게이트 통과 이전에 기록하면 재개 시 미승인 게이트를 건너뛰는 사고로 이어진다.
|
|
10
12
|
|
|
11
13
|
## 형식
|
|
12
14
|
|
|
13
15
|
```
|
|
14
|
-
[YYYY-MM-DDTHH:MM:SSZ]
|
|
16
|
+
[YYYY-MM-DDTHH:MM:SSZ] EVENT — description
|
|
15
17
|
```
|
|
16
18
|
|
|
17
|
-
##
|
|
19
|
+
## 이벤트 체계 (orchestrator 기록)
|
|
18
20
|
|
|
19
|
-
|
|
|
20
|
-
|
|
21
|
-
|
|
|
22
|
-
|
|
|
23
|
-
|
|
|
24
|
-
|
|
|
25
|
-
|
|
|
26
|
-
|
|
|
21
|
+
| 이벤트 | 기록 시점 | 예시 |
|
|
22
|
+
|--------|----------|------|
|
|
23
|
+
| `ORCHESTRATOR_START` | orchestrator 실행 시작 | `ORCHESTRATOR_START — WORK-NN orchestrator started` |
|
|
24
|
+
| `STAGE_START` | 자식 에이전트(specifier/planner/builder/verifier/committer) spawn 직전 | `STAGE_START — stage=specifier` |
|
|
25
|
+
| `GATE_WAIT` | `<gate type="stage">`에서 정지, Main Claude 승인 대기 | `GATE_WAIT — stage=specifier` |
|
|
26
|
+
| `DECISION_WAIT` | `<gate type="decision">` 또는 자식의 `<needs-decision>` 수신 후 결정 대기 | `DECISION_WAIT — stage=planner` |
|
|
27
|
+
| `DECISION` | 결정 확정 — 주체는 `user`(사용자 승인) 또는 `auto`(orchestrator 자동결정) | `DECISION — stage=planner by=user` / `DECISION — task=TASK-03 by=auto` |
|
|
28
|
+
| `STAGE_DONE` | 게이트 해소(RESOLVED) 후, 또는 게이트가 없는 단계는 완료 즉시 | `STAGE_DONE — stage=specifier` |
|
|
29
|
+
| `ORCHESTRATOR_DONE` | orchestrator 실행 종료 (WORK 완료) | `ORCHESTRATOR_DONE — WORK-NN orchestrator completed` |
|
|
30
|
+
|
|
31
|
+
- `stage` 값: `specifier`/`planner`/`builder`/`verifier`/`committer`.
|
|
32
|
+
- `by` 값: `user`/`auto`. `<decision>`(§ 7, `xml-schema.md`)의 `by` 속성과 동일한 값 체계를 사용.
|
|
33
|
+
- 확정된 결정의 상세 내용(배경/선택지/권고안/확정값)은 로그가 아니라 `works/{WORK_ID}/DECISIONS.md`에 기록한다 → `file-content-schema.md` § 4 참조. 로그의 `DECISION` 이벤트는 "언제·누가 결정했는지"만 남긴다.
|