uctm 2.0.0 → 2.0.1
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 +1 -1
- package/README.md +30 -16
- package/agents/builder.md +2 -8
- package/agents/committer.md +5 -12
- package/agents/orchestrator.md +89 -7
- package/agents/planner.md +3 -8
- package/agents/specifier.md +3 -8
- package/agents/verifier.md +2 -7
- package/lib/constants.mjs +30 -2
- package/lib/init.mjs +13 -1
- package/lib/update.mjs +9 -1
- package/package.json +1 -1
- package/references/agent-flow.md +48 -7
- package/references/context-policy.md +24 -7
- package/references/file-content-schema.md +20 -0
- package/references/shared-prompt-sections.md +23 -2
- package/references/work-activity-log.md +22 -5
- package/references/xml-schema.md +115 -40
- package/skills/work-pipeline/SKILL.md +16 -1
- package/references/ref-cache-protocol.md +0 -31
package/README.md
CHANGED
|
@@ -434,6 +434,20 @@ Main Claude ── spawn once (mode=gated|auto) ──▶ orchestrator
|
|
|
434
434
|
- `mode=auto`: no gates — orchestrator completes the entire diagram in one spawn and records any judgment calls to `DECISIONS.md`.
|
|
435
435
|
- STEP C (the builder → verifier → committer loop) never gates on the user, in either mode.
|
|
436
436
|
|
|
437
|
+
### Degraded Mode (nested spawn unavailable)
|
|
438
|
+
|
|
439
|
+
Some CLI builds do not inject the `Agent` tool into sub-agents, which makes the nested spawn above impossible. Before reading any file, orchestrator checks its own tool list and — if `Agent` is missing — returns immediately without creating a single artifact:
|
|
440
|
+
|
|
441
|
+
```xml
|
|
442
|
+
<capability-degraded reason="no-agent-tool">
|
|
443
|
+
<detail>Agent tool not injected into sub-agent; nested spawn unavailable</detail>
|
|
444
|
+
</capability-degraded>
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
**Main Claude then takes over the orchestrator role**: it reads `orchestrator.md` plus the 5 reference files and runs the same procedure, spawning the five children directly at depth 1. ref-cache assembly, the activity log, TASK DAG scheduling, and the retry rules are all unchanged; gates are raised by asking the user directly instead of via `<gate>` XML.
|
|
448
|
+
|
|
449
|
+
> This check exists because the failure is silent otherwise. Without it, orchestrator performs every role inline and reports success — the WORK looks complete while role separation and verification independence are gone.
|
|
450
|
+
|
|
437
451
|
### Stage Detail
|
|
438
452
|
|
|
439
453
|
```
|
|
@@ -463,7 +477,7 @@ Six agents work together in a clean, isolated pipeline — Main Claude spawns on
|
|
|
463
477
|
|
|
464
478
|
### Support Files (included in Plugin)
|
|
465
479
|
|
|
466
|
-
In addition to the 6 pipeline agents, the plugin includes
|
|
480
|
+
In addition to the 6 pipeline agents, the plugin includes 6 support files. **Only the orchestrator reads them** — child agents receive the sections they need via ref-cache (see below).
|
|
467
481
|
These are located in `plugin/references/` (synced from `develop/references/`); when installed via npm they land in `.claude/references/`:
|
|
468
482
|
|
|
469
483
|
| File | Purpose |
|
|
@@ -471,10 +485,11 @@ These are located in `plugin/references/` (synced from `develop/references/`); w
|
|
|
471
485
|
| `agent-flow.md` | Pipeline orchestration rules — Main Claude's trigger/gate boundary + orchestrator's internal nested-spawn flow |
|
|
472
486
|
| `context-policy.md` | Sliding window context transfer rules between agents |
|
|
473
487
|
| `file-content-schema.md` | Single source of truth for all file formats (PLAN.md, TASK.md, progress.md, result.md) |
|
|
474
|
-
| `
|
|
475
|
-
| `shared-prompt-sections.md` | Shared prompt sections with cache_control — reduces repeated token cost up to 90% |
|
|
488
|
+
| `shared-prompt-sections.md` | Shared prompt sections reused across agents |
|
|
476
489
|
| `work-activity-log.md` | Activity log format for builder stage tracking |
|
|
477
|
-
| `xml-schema.md` | XML communication format for dispatch and task-result messages |
|
|
490
|
+
| `xml-schema.md` | XML communication format for dispatch and task-result messages — also the normative ref-cache protocol (§ 4) |
|
|
491
|
+
|
|
492
|
+
Each of the five files consumed via ref-cache (`context-policy`, `file-content-schema`, `shared-prompt-sections`, `work-activity-log`, `xml-schema`) carries a **section consumption matrix** at the top, declaring which agents need which `§` sections. That matrix is what the orchestrator slices against.
|
|
478
493
|
|
|
479
494
|
---
|
|
480
495
|
|
|
@@ -650,17 +665,17 @@ Each agent file follows a consistent four-section structure:
|
|
|
650
665
|
|
|
651
666
|
### ref-cache: Reference File Caching
|
|
652
667
|
|
|
653
|
-
|
|
668
|
+
Without caching, every agent re-reads 3-5 shared reference files at startup — roughly 40+ reads across a 3-TASK pipeline. **ref-cache** makes the orchestrator the single reader:
|
|
654
669
|
|
|
655
|
-
1. **
|
|
656
|
-
2. **
|
|
657
|
-
3. **
|
|
670
|
+
1. **Orchestrator** reads the 5 reference files once at startup, and parses each file's section consumption matrix
|
|
671
|
+
2. **Before every nested spawn**, it slices out only the `§` sections that specific child needs and assembles a `<ref-cache>` with a `sections="..."` attribute per file
|
|
672
|
+
3. **Child agents never touch disk** for references — reading anything under `{REFERENCES_DIR}` is prohibited. Each child cross-checks the received `sections` against its own required-section list, and escalates a `<needs-decision>` if anything is missing rather than falling back to a disk read
|
|
658
673
|
|
|
659
|
-
The protocol
|
|
674
|
+
The protocol is normatively defined in `references/xml-schema.md` § 4. The per-agent section mapping lives in the **section consumption matrix at the top of each reference file** — not in a separate mapping document, so a file and its distribution rules stay together.
|
|
660
675
|
|
|
661
|
-
**
|
|
662
|
-
-
|
|
663
|
-
- Token usage:
|
|
676
|
+
**Design target** (3-TASK WORK):
|
|
677
|
+
- Reference file reads: ~42 → **5** (orchestrator startup only)
|
|
678
|
+
- Token usage: reduced proportionally to section slicing — each child receives only its own sections instead of whole files
|
|
664
679
|
|
|
665
680
|
### WORK ID Assignment Strategy
|
|
666
681
|
|
|
@@ -878,14 +893,13 @@ uc-taskmanager/
|
|
|
878
893
|
│ │ ├── builder.md ← Code implementation
|
|
879
894
|
│ │ ├── verifier.md ← Build/lint/test verification
|
|
880
895
|
│ │ └── committer.md ← git commit + result.md
|
|
881
|
-
│ ├── references/ ←
|
|
896
|
+
│ ├── references/ ← 6 support files (read by the orchestrator only)
|
|
882
897
|
│ │ ├── agent-flow.md ← Pipeline orchestration rules
|
|
883
898
|
│ │ ├── context-policy.md ← Sliding window context rules
|
|
884
899
|
│ │ ├── file-content-schema.md ← File format definitions
|
|
885
|
-
│ │ ├──
|
|
886
|
-
│ │ ├── shared-prompt-sections.md ← Cacheable shared sections
|
|
900
|
+
│ │ ├── shared-prompt-sections.md ← Shared reusable sections
|
|
887
901
|
│ │ ├── work-activity-log.md ← Activity log format
|
|
888
|
-
│ │ └── xml-schema.md ← XML communication format
|
|
902
|
+
│ │ └── xml-schema.md ← XML communication format + ref-cache protocol (§ 4)
|
|
889
903
|
│ ├── skills/ ← Skill definitions (sdd-pipeline, uctm-init, work-pipeline, work-status)
|
|
890
904
|
│ └── .claude-plugin/
|
|
891
905
|
│ └── plugin.json ← Plugin manifest source (name, version, agents array)
|
package/agents/builder.md
CHANGED
|
@@ -30,15 +30,9 @@ model: sonnet
|
|
|
30
30
|
|
|
31
31
|
### 3-1. 사전작업
|
|
32
32
|
|
|
33
|
-
#### STEP 1. STARTUP — 레퍼런스
|
|
33
|
+
#### STEP 1. STARTUP — 레퍼런스 참조
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
`{REFERENCES_DIR}/`에서 다음 파일을 읽기:
|
|
38
|
-
1. `file-content-schema.md`
|
|
39
|
-
2. `shared-prompt-sections.md`
|
|
40
|
-
3. `xml-schema.md`
|
|
41
|
-
4. `context-policy.md`
|
|
35
|
+
`<ref-cache>`를 참조하여 작업을 수행한다.
|
|
42
36
|
|
|
43
37
|
### 3-2. 구현
|
|
44
38
|
|
package/agents/committer.md
CHANGED
|
@@ -29,16 +29,9 @@ model: haiku
|
|
|
29
29
|
|
|
30
30
|
### 3-1. 사전작업
|
|
31
31
|
|
|
32
|
-
#### STEP 1. STARTUP — 레퍼런스
|
|
32
|
+
#### STEP 1. STARTUP — 레퍼런스 참조
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
`{REFERENCES_DIR}/`에서 다음 파일을 읽기:
|
|
37
|
-
1. `file-content-schema.md`
|
|
38
|
-
2. `shared-prompt-sections.md`
|
|
39
|
-
3. `xml-schema.md`
|
|
40
|
-
4. `context-policy.md`
|
|
41
|
-
5. `work-activity-log.md` (STEP 3의 마지막 TASK 판정을 위해 이벤트 형식 참조 — 로그 기록 목적 아님)
|
|
34
|
+
`<ref-cache>`를 참조하여 작업을 수행한다.
|
|
42
35
|
|
|
43
36
|
### 3-2. 커밋 수행
|
|
44
37
|
|
|
@@ -58,7 +51,7 @@ model: haiku
|
|
|
58
51
|
|
|
59
52
|
#### STEP 2. 결과 보고서 생성
|
|
60
53
|
|
|
61
|
-
→ `
|
|
54
|
+
→ `file-content-schema.md` § 3 참조 (형식 + 언어별 섹션 헤더)
|
|
62
55
|
|
|
63
56
|
`works/{WORK_ID}/TASK-XX_result.md` 생성.
|
|
64
57
|
- builder context-handoff `what` → "Builder Context" 섹션
|
|
@@ -75,7 +68,7 @@ STAGE_DONE(stage=committer) 수 + 1 (현재) >= 전체 TASK 수이면:
|
|
|
75
68
|
WORK-LIST.md에서 IN_PROGRESS → DONE으로 변경 (행 제거나 폴더 이동 금지)
|
|
76
69
|
```
|
|
77
70
|
|
|
78
|
-
→ `
|
|
71
|
+
→ `shared-prompt-sections.md` § 8 참조
|
|
79
72
|
|
|
80
73
|
#### STEP 4. Git 확인
|
|
81
74
|
|
|
@@ -154,7 +147,7 @@ Committer 전용 추가 필드:
|
|
|
154
147
|
</next-tasks>
|
|
155
148
|
```
|
|
156
149
|
|
|
157
|
-
→ `
|
|
150
|
+
→ `shared-prompt-sections.md` § 8 참조
|
|
158
151
|
|
|
159
152
|
#### 출력 규칙
|
|
160
153
|
- task-result XML **만** 반환. XML 앞뒤에 요약, 설명, 부연을 추가하지 말 것.
|
package/agents/orchestrator.md
CHANGED
|
@@ -40,8 +40,40 @@ model: opus
|
|
|
40
40
|
|
|
41
41
|
### 3-1. 사전작업
|
|
42
42
|
|
|
43
|
+
#### STEP 0. 능력 확인 — 중첩 spawn 가능 여부 (최우선)
|
|
44
|
+
|
|
45
|
+
**다른 어떤 일보다 먼저 수행한다. 파일을 읽기 전에 판정한다.**
|
|
46
|
+
|
|
47
|
+
자신의 도구 목록에 `Agent` 도구가 있는지 확인한다.
|
|
48
|
+
|
|
49
|
+
| 판정 | 처리 |
|
|
50
|
+
|------|------|
|
|
51
|
+
| `Agent` 있음 | 정상 경로 — STEP 1로 진행 |
|
|
52
|
+
| `Agent` 없음 | **축퇴** — 아래 절차 |
|
|
53
|
+
|
|
54
|
+
**축퇴 시 (`Agent` 도구 없음)**
|
|
55
|
+
|
|
56
|
+
일부 CLI 버전·환경에서는 서브에이전트에 `Agent` 도구가 주입되지 않아 중첩 spawn이 불가능하다. 이때:
|
|
57
|
+
|
|
58
|
+
1. **어떤 작업도 인라인으로 수행하지 않는다.** specifier/planner/builder/verifier/committer 역할을 스스로 대신하는 것은 **금지**다.
|
|
59
|
+
2. **어떤 파일도 읽지 않는다.** 레퍼런스도, 다른 문서도 읽지 않는다. `Read`/`Glob`/`Grep`을 **단 한 번도 호출하지 않는다.**
|
|
60
|
+
3. WORK 폴더·Requirement.md·PLAN.md 등 산출물을 만들지 않는다. 활동 로그도 기록하지 않는다.
|
|
61
|
+
4. **첫 응답으로** 아래 XML을 그대로 반환하고 **즉시 종료**한다.
|
|
62
|
+
|
|
63
|
+
```xml
|
|
64
|
+
<capability-degraded reason="no-agent-tool">
|
|
65
|
+
<detail>서브에이전트에 Agent 도구가 주입되지 않아 중첩 spawn 불가</detail>
|
|
66
|
+
</capability-degraded>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
> 위 XML이 반환에 필요한 전부다. **형식을 확인하려고 `xml-schema.md`를 읽지 말 것** — 위 블록을 그대로 복사하면 된다. 이 단계에서 어떤 파일이든 읽는 것은 규칙 위반이다.
|
|
70
|
+
|
|
71
|
+
> ⚠️ 이 판정을 무시하고 혼자 파이프라인을 수행하면, 겉보기에는 WORK가 완료된 것처럼 보이지만 실제로는 단일 에이전트가 모든 역할을 수행한 것이 되어 파이프라인의 역할 분리·검증 독립성이 모두 무너진다. 오류 없이 조용히 잘못되는 것이 가장 위험하므로 **반드시 즉시 반환**한다.
|
|
72
|
+
|
|
43
73
|
#### STEP 1. STARTUP — 레퍼런스 파일 즉시 읽기 (필수)
|
|
44
74
|
|
|
75
|
+
> **선행 조건**: STEP 0에서 `Agent` 도구가 있다고 판정된 경우에만 이 단계를 수행한다. 축퇴로 판정됐으면 이 단계에 진입하지 않는다.
|
|
76
|
+
|
|
45
77
|
**REFERENCES_DIR 확인**: 입력에서 `REFERENCES_DIR=...` 라인 또는 `<references-dir>` XML 요소를 확인. 해당 절대 경로 사용. 없으면 `.claude/references`를 기본값으로 사용.
|
|
46
78
|
|
|
47
79
|
`{REFERENCES_DIR}/`에서 다음 파일을 읽기:
|
|
@@ -51,7 +83,44 @@ model: opus
|
|
|
51
83
|
4. `work-activity-log.md`
|
|
52
84
|
5. `context-policy.md`
|
|
53
85
|
|
|
54
|
-
|
|
86
|
+
**레퍼런스를 읽는 주체는 orchestrator 하나뿐이다.** 자식은 디스크를 읽지 않고 orchestrator가 전달한 `<ref-cache>`만 사용한다(→ `xml-schema.md` § 4). 따라서 이 5회 읽기가 WORK 전체에서 발생하는 유일한 레퍼런스 읽기다.
|
|
87
|
+
|
|
88
|
+
각 파일 상단의 **`## 섹션 소비 매트릭스`** 표를 함께 파싱해 자식별 섹션 배분표를 확정한다. 이 표가 STEP 1-1 조립의 유일한 기준이다.
|
|
89
|
+
|
|
90
|
+
#### STEP 1-1. ref-cache 조립 (자식 spawn 직전 매회 수행)
|
|
91
|
+
|
|
92
|
+
자식을 중첩 spawn하기 직전, 대상 자식 전용 `<ref-cache>`를 조립한다.
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
1. 대상 자식(specifier/planner/builder/verifier/committer)을 확정한다.
|
|
96
|
+
2. 읽어둔 레퍼런스 5종의 "섹션 소비 매트릭스"에서 해당 자식 열이 ✅인 행을 모은다.
|
|
97
|
+
표를 끝까지 훑어 ✅ 행을 하나도 빠뜨리지 않는다.
|
|
98
|
+
3. ✅ 행이 하나도 없는 파일은 <ref>를 만들지 않는다.
|
|
99
|
+
4. ✅ 행이 있는 파일마다 <ref>를 **정확히 1개씩만** 만든다.
|
|
100
|
+
- 같은 key로 <ref>를 두 번 넣지 않는다.
|
|
101
|
+
- sections 속성에 그 파일의 ✅ 번호를 빠짐없이 나열한다.
|
|
102
|
+
- 본문은 해당 § 원문을 `## § N.` 헤딩째 발췌한다.
|
|
103
|
+
<ref key="{파일명}" sections="{§ 번호 목록}">{원문}</ref>
|
|
104
|
+
5. 조립 결과를 dispatch XML 최상단 <ref-cache>에 넣는다.
|
|
105
|
+
6. spawn 직전 자체 점검 (필수) — 아래 "자식별 조립 결과 요약" 표의 해당 행과 대조한다.
|
|
106
|
+
- key가 중복된 <ref>가 없는가
|
|
107
|
+
- key 구성과 각 sections 값이 표와 정확히 일치하는가
|
|
108
|
+
불일치하면 고친 뒤 spawn한다.
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
> ⚠️ 자주 나오는 두 가지 실수 — ① 같은 파일을 `<ref>` 두 개로 중복 첨부(토큰 낭비), ② 매트릭스의 ✅ 를 일부 빠뜨림(자식이 필요한 내용을 못 받음). 6단계 대조로 둘 다 막는다.
|
|
112
|
+
|
|
113
|
+
자식별 조립 결과 요약(매트릭스에서 유도되는 값 — 표가 갱신되면 표를 따른다):
|
|
114
|
+
|
|
115
|
+
| 자식 | ref-cache 구성 |
|
|
116
|
+
|------|----------------|
|
|
117
|
+
| specifier | `file-content-schema`(준수사항,0,5) · `shared-prompt-sections`(1,3,8,9,12) · `xml-schema`(1,2,6) |
|
|
118
|
+
| planner | `file-content-schema`(준수사항,0,1,2,5) · `shared-prompt-sections`(1,3,7,12) · `xml-schema`(1,2,6) |
|
|
119
|
+
| builder | `file-content-schema`(준수사항,2,3,5) · `shared-prompt-sections`(1,2,3,5,12) · `xml-schema`(1,2,3,6) · `context-policy`(1,2,3,4) |
|
|
120
|
+
| verifier | `file-content-schema`(준수사항,2,5) · `shared-prompt-sections`(1,2,3,5,12) · `xml-schema`(1,2,3,6) · `context-policy`(1,2,3) |
|
|
121
|
+
| committer | `file-content-schema`(준수사항,3,5) · `shared-prompt-sections`(1,3,5,8,12) · `xml-schema`(1,2,3,6) · `context-policy`(1,2,3) · `work-activity-log`(2,3) |
|
|
122
|
+
|
|
123
|
+
> `<ref-cache>` 없이 자식을 spawn하는 것은 **금지**다(→ § 3-5). 자식이 레퍼런스를 다시 읽게 되어 ref-cache가 무력화된다.
|
|
55
124
|
|
|
56
125
|
#### STEP 2. 입력 파싱
|
|
57
126
|
|
|
@@ -86,7 +155,8 @@ model: opus
|
|
|
86
155
|
#### STEP A. Specifier 중첩 spawn (WORK 생성)
|
|
87
156
|
|
|
88
157
|
- 활동 로그 `STAGE_START — stage=specifier` 기록.
|
|
89
|
-
- specifier
|
|
158
|
+
- **specifier용 `<ref-cache>`를 STEP 1-1 절차로 조립한다** — `file-content-schema`(준수사항,0,5) · `shared-prompt-sections`(1,3,8,9,12) · `xml-schema`(1,2,6).
|
|
159
|
+
- specifier를 중첩 spawn. 프롬프트에 사용자 요청 원문과 **조립한 `<ref-cache>`(필수)** 를 포함. `REFERENCES_DIR`는 자식에게 전달하지 않는다(→ § 3-5).
|
|
90
160
|
- 반환값에서 WORK 폴더/Requirement.md 생성 여부를 확인.
|
|
91
161
|
- **게이트 처리**:
|
|
92
162
|
- `mode=gated`: `GATE_WAIT — stage=specifier` 기록 → `[GATE-1] <gate type="stage" work="{WORK}" stage="specifier">` + Requirement 요약(`<next-stage>planner</next-stage>`) 반환 후 **yield**.
|
|
@@ -94,7 +164,8 @@ model: opus
|
|
|
94
164
|
|
|
95
165
|
#### STEP B. Planner 중첩 spawn
|
|
96
166
|
|
|
97
|
-
- planner
|
|
167
|
+
- **planner용 `<ref-cache>`를 STEP 1-1 절차로 조립한다** — `file-content-schema`(준수사항,0,1,2,5) · `shared-prompt-sections`(1,3,7,12) · `xml-schema`(1,2,6).
|
|
168
|
+
- planner를 중첩 spawn(**조립한 `<ref-cache>` 필수 포함**) → `PLAN.md` + `TASK-NN.md` DAG 생성.
|
|
98
169
|
- 활동 로그 `STAGE_START — stage=planner`.
|
|
99
170
|
- **게이트 처리**:
|
|
100
171
|
- `mode=gated`: `GATE_WAIT — stage=planner` 기록 → `[GATE-2] <gate type="stage" work="{WORK}" stage="planner">` + PLAN/TASK 요약(`<next-stage>builder</next-stage>`) 반환 후 **yield**.
|
|
@@ -106,10 +177,10 @@ model: opus
|
|
|
106
177
|
|
|
107
178
|
1. `works/{WORK}/work_{WORK}.log` + `PLAN.md`로 DAG 해석 → 각 TASK 상태(DONE/READY/BLOCKED) 판정(→ `shared-prompt-sections.md` § 4).
|
|
108
179
|
2. READY TASK를 오름차순으로 선택. **복수 READY**면 builder를 동시에(같은 턴에 여러 spawn 호출을 묶어) 병렬 중첩 spawn.
|
|
109
|
-
3. TASK별로 builder → verifier → committer를 순차 중첩 spawn
|
|
110
|
-
- `STAGE_START — stage=builder task=TASK-NN` 기록 → builder spawn → 결과 확인.
|
|
111
|
-
- `STAGE_START — stage=verifier task=TASK-NN` 기록 → verifier spawn (builder context-handoff FULL 전달) → FAIL이면 builder 재디스패치.
|
|
112
|
-
- `STAGE_START — stage=committer task=TASK-NN` 기록 → committer spawn (verifier FULL + builder SUMMARY 전달) → FAIL이면 builder 재디스패치.
|
|
180
|
+
3. TASK별로 builder → verifier → committer를 순차 중첩 spawn. **매 spawn마다 STEP 1-1로 해당 자식용 `<ref-cache>`를 조립해 필수 포함한다**:
|
|
181
|
+
- `STAGE_START — stage=builder task=TASK-NN` 기록 → builder spawn (`<ref-cache>`: `file-content-schema`(준수사항,2,3,5) · `shared-prompt-sections`(1,2,3,5,12) · `xml-schema`(1,2,3,6) · `context-policy`(1,2,3,4)) → 결과 확인.
|
|
182
|
+
- `STAGE_START — stage=verifier task=TASK-NN` 기록 → verifier spawn (`<ref-cache>`: `file-content-schema`(준수사항,2,5) · `shared-prompt-sections`(1,2,3,5,12) · `xml-schema`(1,2,3,6) · `context-policy`(1,2,3), + builder context-handoff FULL 전달) → FAIL이면 builder 재디스패치.
|
|
183
|
+
- `STAGE_START — stage=committer task=TASK-NN` 기록 → committer spawn (`<ref-cache>`: `file-content-schema`(준수사항,3,5) · `shared-prompt-sections`(1,3,5,8,12) · `xml-schema`(1,2,3,6) · `context-policy`(1,2,3) · `work-activity-log`(2,3), + verifier FULL + builder SUMMARY 전달) → FAIL이면 builder 재디스패치.
|
|
113
184
|
- 각 단계는 게이트가 없으므로 성공 시 즉시 `STAGE_DONE — stage={builder|verifier|committer} task=TASK-NN` 기록.
|
|
114
185
|
4. **재시도**: verifier 또는 committer가 FAIL 반환 → builder에 최대 2회 재디스패치(총 3회 시도) (→ `context-policy.md` Committer 재시도 절 준용).
|
|
115
186
|
- 3회 모두 실패 → 자식이 직접 파이프라인을 중단하지 않고, orchestrator에 `<needs-decision>`으로 상향(판단 기준 "재시도 3회 실패" 해당, → 3-3 절 참조)한다. `mode=gated`면 게이트로 승격해 사용자에게 TASK 보류/스킵/중단을 묻고, `mode=auto`면 권고안(보통 "해당 TASK FAILED 표시 후 나머지 TASK 계속")을 자동결정해 기록한다.
|
|
@@ -159,6 +230,14 @@ model: opus
|
|
|
159
230
|
- 파괴적/비가역적 변경 (데이터 삭제, 스키마 breaking change 등)
|
|
160
231
|
- 재시도 3회 실패 (STEP C 참조)
|
|
161
232
|
|
|
233
|
+
**예외 — ref-cache 내용 부족**
|
|
234
|
+
|
|
235
|
+
자식이 "ref-cache에 필요한 내용이 없다"는 사유로 `<needs-decision>`을 올리면 이는 사용자 결정 사항이 **아니다**. 게이트로 승격하지 말고 orchestrator가 즉시 처리한다:
|
|
236
|
+
1. 부족하다고 보고된 `key`·내용을 확인한다.
|
|
237
|
+
2. 해당 § 원문을 이미 읽어둔 레퍼런스에서 발췌해 `<ref-cache>`에 보충한다.
|
|
238
|
+
3. 보충된 `<ref-cache>`로 해당 자식을 재spawn한다(로그·게이트 발생 없음).
|
|
239
|
+
4. 섹션 소비 매트릭스의 배분이 실제 필요와 어긋났다는 신호이므로, 최종 보고서 `## 자동 결정 사항`에 그 사실을 1줄로 남긴다.
|
|
240
|
+
|
|
162
241
|
**에스컬레이션 처리**
|
|
163
242
|
- `mode=gated`: 위 기준에 해당 → `DECISION_WAIT — stage={agent}[ task=TASK-NN]` 기록, `DECISIONS.md`에 `상태: PENDING` 항목 추가 → `<gate type="decision" work stage>`(`<context>`/`<options>`/`<recommended>` 포함, → `xml-schema.md` § 5) 반환 후 **yield**. 재개 시 Main Claude가 전달한 `<decision by="user">`(§ 7)를 받아 `DECISIONS.md`를 `RESOLVED`로 갱신하고 `DECISION — ... by=user` 기록 후 해당 자식을 재개/재spawn.
|
|
164
243
|
- 위 기준에 해당하지 않는 경미한 사항(자동 결정 가능)은 게이트 없이 orchestrator가 즉시 `<decision by="auto">`로 확정하고 자식 작업을 재개시킬 수 있다(→ `xml-schema.md` § 6) — 모든 needs-decision이 반드시 사용자에게 올라가는 것은 아니다.
|
|
@@ -187,6 +266,9 @@ TASK 간 의존성 전달(builder→verifier→committer, 그리고 다음 TASK
|
|
|
187
266
|
| WORK 범위 고정 | 지정된 WORK 내 TASK만 처리, 다른 WORK와 혼합 금지 |
|
|
188
267
|
| 게이트 우회 금지 | `mode=gated`에서 고정 게이트·동적 decision 게이트를 임의로 스킵하거나 자동결정으로 대체하지 않음 |
|
|
189
268
|
| STAGE_DONE 선기록 금지 | 게이트가 있는 단계는 게이트 해소(RESOLVED) 이전에 `STAGE_DONE`을 기록하지 않음 |
|
|
269
|
+
| 인라인 역할 대행 금지 | `Agent` 도구가 없어 중첩 spawn이 불가능하면(→ STEP 0) 자식 역할을 스스로 수행하지 않고 `<capability-degraded>`를 반환하고 종료한다. 혼자 수행하면 오류 없이 역할 분리가 무너진 채 완료된 것처럼 보인다 |
|
|
270
|
+
| ref-cache 미첨부 spawn 금지 | 자식 중첩 spawn 시 `<ref-cache>`를 반드시 포함(→ STEP 1-1). 누락하면 자식이 레퍼런스를 디스크에서 다시 읽어 캐시가 무력화된다 |
|
|
271
|
+
| 자식 레퍼런스 읽기 금지 | 레퍼런스 파일을 읽는 주체는 orchestrator뿐. 자식 프롬프트에 `REFERENCES_DIR`나 레퍼런스 파일 경로를 **넣지 않는다** — 경로가 보이면 자식이 읽으려 든다 |
|
|
190
272
|
| 파킹 핸들 1개 원칙 | orchestrator 자신만 파킹 대상 — 자식은 실행→반환하면 종료, 능동 관리 대상 아님 |
|
|
191
273
|
| 재개 시 재실행 최소화 | `GATE_WAIT`/`DECISION_WAIT`로 종료된 경우 자식을 재실행하지 않고 디스크 산출물을 재사용 |
|
|
192
274
|
|
package/agents/planner.md
CHANGED
|
@@ -33,14 +33,9 @@ WORK (작업 단위) — 사용자 요청의 목표 단위
|
|
|
33
33
|
|
|
34
34
|
### 3-1. 사전작업
|
|
35
35
|
|
|
36
|
-
#### STEP 1. STARTUP — 레퍼런스
|
|
36
|
+
#### STEP 1. STARTUP — 레퍼런스 참조
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
`{REFERENCES_DIR}/`에서 다음 파일을 읽기:
|
|
41
|
-
1. `file-content-schema.md`
|
|
42
|
-
2. `shared-prompt-sections.md`
|
|
43
|
-
3. `xml-schema.md`
|
|
38
|
+
`<ref-cache>`를 참조하여 작업을 수행한다.
|
|
44
39
|
|
|
45
40
|
### STEP 2. WORK 확인
|
|
46
41
|
|
|
@@ -102,7 +97,7 @@ specifier가 판정한 복잡도를 참고해 TASK 분해 단위를 정한다.
|
|
|
102
97
|
|
|
103
98
|
## 6. 승인요청
|
|
104
99
|
|
|
105
|
-
- 승인 요청은 planner가 직접 수행하지 않는다 — orchestrator가 `<gate
|
|
100
|
+
- 승인 요청은 planner가 직접 수행하지 않는다 — gated 모드에서는 orchestrator가 `<gate>`를 발행해 상위 경계에서 승인을 처리한다. planner는 `<gate>`를 생성하지 않는다.
|
|
106
101
|
|
|
107
102
|
## 7. 결과 보고
|
|
108
103
|
정의된 역할을 모두 끝내면 orchestrator에 보고해. 미해결 모호점이 있으면 `<needs-decision>`을 함께 반환해.
|
package/agents/specifier.md
CHANGED
|
@@ -33,14 +33,9 @@ model: opus
|
|
|
33
33
|
|
|
34
34
|
## 3-1. 사전작업
|
|
35
35
|
|
|
36
|
-
### STEP 1. STARTUP — 레퍼런스
|
|
36
|
+
### STEP 1. STARTUP — 레퍼런스 참조
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
`{REFERENCES_DIR}/`에서 다음 파일을 읽기:
|
|
41
|
-
1. `file-content-schema.md`
|
|
42
|
-
2. `shared-prompt-sections.md`
|
|
43
|
-
3. `xml-schema.md`
|
|
38
|
+
`<ref-cache>`를 참조하여 작업을 수행한다.
|
|
44
39
|
|
|
45
40
|
### STEP 2. WORK ID 결정
|
|
46
41
|
```
|
|
@@ -339,7 +334,7 @@ model: opus
|
|
|
339
334
|
|
|
340
335
|
## 6. 승인요청
|
|
341
336
|
|
|
342
|
-
- 승인 요청은 specifier가 직접 수행하지 않는다 — orchestrator가 `<gate
|
|
337
|
+
- 승인 요청은 specifier가 직접 수행하지 않는다 — gated 모드에서는 orchestrator가 `<gate>`를 발행해 상위 경계에서 승인을 처리한다. specifier는 `<gate>`를 생성하지 않는다.
|
|
343
338
|
- specifier는 명세서 요약 + 복잡도 판정 결과를 반환하는 것으로 역할을 마친다.
|
|
344
339
|
|
|
345
340
|
## 7. Planner Agent역할 수행 (필요 시)
|
package/agents/verifier.md
CHANGED
|
@@ -31,14 +31,9 @@ Builder가 완료한 TASK의 결과를 검증하여 빌드, 린트, 테스트, A
|
|
|
31
31
|
|
|
32
32
|
### 3-1. 사전작업
|
|
33
33
|
|
|
34
|
-
#### STEP 1. STARTUP — 레퍼런스
|
|
34
|
+
#### STEP 1. STARTUP — 레퍼런스 참조
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
`{REFERENCES_DIR}/`에서 다음 파일을 읽기:
|
|
39
|
-
1. `shared-prompt-sections.md`
|
|
40
|
-
2. `xml-schema.md`
|
|
41
|
-
3. `context-policy.md`
|
|
36
|
+
`<ref-cache>`를 참조하여 작업을 수행한다.
|
|
42
37
|
|
|
43
38
|
### 3-2. 검증
|
|
44
39
|
|
package/lib/constants.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readFileSync } from 'node:fs';
|
|
1
|
+
import { readFileSync, existsSync, rmSync } from 'node:fs';
|
|
2
2
|
import { join, dirname } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
|
|
@@ -20,7 +20,6 @@ export const REFERENCE_FILES = [
|
|
|
20
20
|
'agent-flow.md',
|
|
21
21
|
'context-policy.md',
|
|
22
22
|
'file-content-schema.md',
|
|
23
|
-
'ref-cache-protocol.md',
|
|
24
23
|
'shared-prompt-sections.md',
|
|
25
24
|
'work-activity-log.md',
|
|
26
25
|
'xml-schema.md',
|
|
@@ -34,6 +33,35 @@ export function getReferencesSrcDir() {
|
|
|
34
33
|
return join(__dirname, '..', 'references');
|
|
35
34
|
}
|
|
36
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Files and directories shipped by earlier versions that no longer exist.
|
|
38
|
+
* init and update copy files but never delete, so an upgraded install keeps
|
|
39
|
+
* stale copies unless they are pruned explicitly.
|
|
40
|
+
*
|
|
41
|
+
* Paths are relative to the install root (.claude/ or ~/.claude/).
|
|
42
|
+
*/
|
|
43
|
+
export const OBSOLETE_PATHS = [
|
|
44
|
+
'agents/scheduler.md', // removed in 2.0.0 — orchestrator took over scheduling
|
|
45
|
+
'references/callback-protocol.md', // removed in 2.0.0 — external callback integration dropped
|
|
46
|
+
'references/ref-cache-protocol.md',// removed in 2.1.0 — protocol folded into xml-schema.md § 4
|
|
47
|
+
'skills/sdd-pipeline/references', // removed in 1.5.0 — references moved to references/
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Delete every OBSOLETE_PATHS entry that still exists under baseDir.
|
|
52
|
+
* Returns the paths actually removed.
|
|
53
|
+
*/
|
|
54
|
+
export function pruneObsolete(baseDir) {
|
|
55
|
+
const removed = [];
|
|
56
|
+
for (const relPath of OBSOLETE_PATHS) {
|
|
57
|
+
const target = join(baseDir, relPath);
|
|
58
|
+
if (!existsSync(target)) continue;
|
|
59
|
+
rmSync(target, { recursive: true, force: true });
|
|
60
|
+
removed.push(relPath);
|
|
61
|
+
}
|
|
62
|
+
return removed;
|
|
63
|
+
}
|
|
64
|
+
|
|
37
65
|
|
|
38
66
|
/**
|
|
39
67
|
* Bash permissions required by uc-taskmanager agents.
|
package/lib/init.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { existsSync, mkdirSync, copyFileSync, readFileSync, writeFileSync, readd
|
|
|
2
2
|
import { join, dirname } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { homedir } from 'node:os';
|
|
5
|
-
import { AGENT_FILES, REFERENCE_FILES, getAgentsSrcDir, getReferencesSrcDir, REQUIRED_PERMISSIONS } from './constants.mjs';
|
|
5
|
+
import { AGENT_FILES, REFERENCE_FILES, getAgentsSrcDir, getReferencesSrcDir, REQUIRED_PERMISSIONS, pruneObsolete } from './constants.mjs';
|
|
6
6
|
|
|
7
7
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
8
|
|
|
@@ -73,6 +73,15 @@ function copyPluginResources(destBaseDir) {
|
|
|
73
73
|
return count;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
function reportPruned(baseDir) {
|
|
77
|
+
const removed = pruneObsolete(baseDir);
|
|
78
|
+
if (removed.length === 0) return;
|
|
79
|
+
console.log(` ${green('✓')} ${removed.length} obsolete files removed`);
|
|
80
|
+
for (const relPath of removed) {
|
|
81
|
+
console.log(` ${dim('-')} ${dim(relPath)}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
76
85
|
function ensureWorksDir(projectDir) {
|
|
77
86
|
const worksDir = join(projectDir, 'works');
|
|
78
87
|
if (existsSync(worksDir)) return false;
|
|
@@ -141,6 +150,7 @@ export async function init(isGlobal) {
|
|
|
141
150
|
if (globalResCount > 0) {
|
|
142
151
|
console.log(` ${green('✓')} ${globalResCount} plugin resource files copied`);
|
|
143
152
|
}
|
|
153
|
+
reportPruned(globalClaudeDir);
|
|
144
154
|
console.log(`\n ${dim('Next steps:')}`);
|
|
145
155
|
console.log(` 1. Open any project and run ${dim("'claude'")}`);
|
|
146
156
|
console.log(` 2. Type: ${dim(exampleTag)}\n`);
|
|
@@ -162,6 +172,8 @@ export async function init(isGlobal) {
|
|
|
162
172
|
console.log(` ${green('✓')} ${resCount} plugin resource files copied (.claude-plugin, skills)`);
|
|
163
173
|
}
|
|
164
174
|
|
|
175
|
+
reportPruned(claudeDir);
|
|
176
|
+
|
|
165
177
|
if (ensureWorksDir(projectDir)) {
|
|
166
178
|
console.log(` ${green('✓')} works/ directory created`);
|
|
167
179
|
} else {
|
package/lib/update.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { existsSync, copyFileSync, mkdirSync } from 'node:fs';
|
|
|
2
2
|
import { join, dirname } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { homedir } from 'node:os';
|
|
5
|
-
import { AGENT_FILES, REFERENCE_FILES, getAgentsSrcDir, getReferencesSrcDir } from './constants.mjs';
|
|
5
|
+
import { AGENT_FILES, REFERENCE_FILES, getAgentsSrcDir, getReferencesSrcDir, pruneObsolete } from './constants.mjs';
|
|
6
6
|
|
|
7
7
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
8
|
|
|
@@ -40,9 +40,17 @@ export function update(isGlobal) {
|
|
|
40
40
|
refCount++;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
const removed = pruneObsolete(baseDir);
|
|
44
|
+
|
|
43
45
|
const label = isGlobal ? '~/.claude/' : '.claude/';
|
|
44
46
|
console.log(`\n Updating ${dim(label)} ...`);
|
|
45
47
|
console.log(` ${green('✓')} ${agentCount} agent files updated`);
|
|
46
48
|
console.log(` ${green('✓')} ${refCount} reference files updated`);
|
|
49
|
+
if (removed.length > 0) {
|
|
50
|
+
console.log(` ${green('✓')} ${removed.length} obsolete files removed`);
|
|
51
|
+
for (const relPath of removed) {
|
|
52
|
+
console.log(` ${dim('-')} ${dim(relPath)}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
47
55
|
console.log(` ${dim('-')} CLAUDE.md untouched\n`);
|
|
48
56
|
}
|
package/package.json
CHANGED
package/references/agent-flow.md
CHANGED
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
> Main Claude는 **트리거와 게이트 경계**만 담당합니다.
|
|
4
4
|
> 파이프라인 내부 진행(WORK 생성 → 설계 → TASK 실행 → 완료)은 **orchestrator**가 전담합니다.
|
|
5
5
|
> Main Claude는 orchestrator 외의 다른 에이전트를 **직접 spawn하지 않습니다**.
|
|
6
|
+
>
|
|
7
|
+
> **예외 — 축퇴 모드(§7)**: 실행 환경이 중첩 spawn을 지원하지 않으면 Main Claude가 orchestrator 역할을 넘겨받아 자식을 직접 spawn합니다.
|
|
6
8
|
|
|
7
9
|
---
|
|
8
10
|
|
|
9
11
|
## 1. Main Claude 역할 (트리거 + 게이트 경계)
|
|
10
12
|
|
|
11
|
-
Main Claude가 직접 수행하는 일은 다음
|
|
13
|
+
Main Claude가 직접 수행하는 일은 다음 5가지뿐입니다.
|
|
12
14
|
|
|
13
15
|
1. **트리거 감지** — `[tag]` 메시지 또는 WORK 재개 요청(예: "WORK-01 계속실행", "resume WORK-01")을 감지.
|
|
14
16
|
2. **orchestrator 1회 spawn** — 다음을 전달:
|
|
@@ -16,14 +18,15 @@ Main Claude가 직접 수행하는 일은 다음 4가지뿐입니다.
|
|
|
16
18
|
- `mode=gated|auto` — 사용자 메시지에 "auto"/"자동으로"가 포함되면 `auto`, 그 외는 기본값 `gated`
|
|
17
19
|
- 사용자 요청 원문 (재개 요청이면 대상 `WORK_ID`)
|
|
18
20
|
- spawn 결과로 받는 **agentId를 보관**한다(재개 시 name이 아니라 **agentId**로 지정 — 이름 재사용 오배달 방지).
|
|
19
|
-
3.
|
|
21
|
+
3. **축퇴 신호 처리** — orchestrator가 `<capability-degraded>`를 반환하면 §7 축퇴 모드로 전환한다.
|
|
22
|
+
4. **게이트 처리** — orchestrator가 `<gate type="stage">` 또는 `<gate type="decision">`을 반환하고 **yield(파킹)** 하면:
|
|
20
23
|
1. 게이트 내용을 사용자에게 그대로 제시한다 — `type="stage"`는 완료 요약, `type="decision"`은 배경(`<context>`) + 선택지(`<options>`) + 권고안(`<recommended>`)(`AskUserQuestion` 등으로 선택 요청).
|
|
21
24
|
2. 사용자의 승인 또는 선택을 기다린다.
|
|
22
25
|
3. 응답을 받으면 **`SendMessage(agentId, 결정내용)`으로 컨텍스트를 유지한 채 재개**한다.
|
|
23
26
|
4. `SendMessage`가 실패하면(파킹 핸들 유실 등) **폴백**: `works/{WORK_ID}/work_{WORK_ID}.log` + `DECISIONS.md`를 근거로 orchestrator를 `WORK_ID`와 함께 새로 spawn해 재개시킨다.
|
|
24
|
-
|
|
27
|
+
5. **완료 처리** — orchestrator가 최종 WORK 요약을 반환하면 사용자에게 그대로 릴레이하고 **`TaskStop(agentId)`로 파킹 핸들을 해제**한다.
|
|
25
28
|
|
|
26
|
-
`mode=auto`인 경우 orchestrator가 게이트/의사결정 정지 없이 1회 spawn으로 완주하므로,
|
|
29
|
+
`mode=auto`인 경우 orchestrator가 게이트/의사결정 정지 없이 1회 spawn으로 완주하므로, 4단계(게이트 처리)는 발생하지 않는다 — Main Claude는 spawn 후 최종 결과만 수신·릴레이하고 `TaskStop`으로 마무리한다.
|
|
27
30
|
|
|
28
31
|
---
|
|
29
32
|
|
|
@@ -155,7 +158,7 @@ Main Claude는 재개 요청을 감지하면 대상 `WORK_ID`를 orchestrator에
|
|
|
155
158
|
## References Directory 전달 (필수)
|
|
156
159
|
|
|
157
160
|
Main Claude는 orchestrator spawn 시(신규/재개 모두) references 디렉토리 경로를 전달해야 합니다.
|
|
158
|
-
설치 방법(npm 또는 plugin)에 관계없이 orchestrator
|
|
161
|
+
설치 방법(npm 또는 plugin)에 관계없이 orchestrator가 레퍼런스 파일을 찾을 수 있도록 합니다. 이 경로를 받는 것은 orchestrator뿐이며, 자식에게는 전달되지 않습니다.
|
|
159
162
|
|
|
160
163
|
**전달 방법:**
|
|
161
164
|
- orchestrator spawn 프롬프트 상단에 `REFERENCES_DIR={absolute_path}` 추가
|
|
@@ -170,10 +173,48 @@ mode=gated
|
|
|
170
173
|
[WORK] 사용자 요청 원문...
|
|
171
174
|
```
|
|
172
175
|
|
|
173
|
-
REFERENCES_DIR를 사용할 수 없는 경우(예: plugin 없는 npm 설치), orchestrator는 `.claude/references/`를 폴백으로 사용합니다. orchestrator는 자신이 읽은 레퍼런스
|
|
176
|
+
REFERENCES_DIR를 사용할 수 없는 경우(예: plugin 없는 npm 설치), orchestrator는 `.claude/references/`를 폴백으로 사용합니다. orchestrator는 자신이 읽은 레퍼런스 중 각 자식에게 필요한 섹션만 잘라 `<ref-cache>`(`xml-schema.md` § 4)로 **반드시** 재전달합니다.
|
|
174
177
|
|
|
175
178
|
---
|
|
176
179
|
|
|
177
180
|
## 레퍼런스 로딩
|
|
178
181
|
|
|
179
|
-
Main Claude는 레퍼런스 파일을 읽지 않으며 — `agent-flow.md`만 읽습니다.
|
|
182
|
+
**정상 경로**: Main Claude는 레퍼런스 파일을 읽지 않으며 — `agent-flow.md`만 읽습니다. `{REFERENCES_DIR}/`의 레퍼런스 파일을 읽는 주체는 **orchestrator 하나뿐**입니다(기동 시 1회, 5개 파일).
|
|
183
|
+
|
|
184
|
+
**축퇴 모드(§7)**: orchestrator 역할이 Main Claude로 넘어오므로 Main Claude가 그 5개 파일을 읽습니다. 읽는 주체만 바뀌고 횟수·범위는 동일합니다.
|
|
185
|
+
|
|
186
|
+
어느 경우든 자식 에이전트(specifier/planner/builder/verifier/committer)는 디스크를 읽지 않고, 각 파일 상단의 **섹션 소비 매트릭스**를 기준으로 잘라 전달된 `<ref-cache>`만 사용합니다 → `xml-schema.md` § 4.
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## 7. 축퇴 모드 — Main Claude가 orchestrator 역할 수행
|
|
191
|
+
|
|
192
|
+
### 진입 조건
|
|
193
|
+
|
|
194
|
+
orchestrator가 `<capability-degraded reason="no-agent-tool">`(→ `xml-schema.md` § 8)을 반환한 경우. 일부 CLI 버전·환경에서 서브에이전트에 `Agent` 도구가 주입되지 않아 중첩 spawn이 불가능할 때 발생합니다. orchestrator는 이때 아무 산출물도 만들지 않고 즉시 반환하므로, 디스크에는 아무것도 남아 있지 않은 상태입니다.
|
|
195
|
+
|
|
196
|
+
### 처리 절차
|
|
197
|
+
|
|
198
|
+
1. **사용자에게 1줄 알린다** — 예: "중첩 spawn을 지원하지 않는 환경입니다. Main Claude가 직접 오케스트레이션합니다." 승인을 기다리지 않고 그대로 진행합니다(`mode=auto`의 무정지 완주 원칙 유지).
|
|
199
|
+
2. **`{REFERENCES_DIR}/orchestrator.md`와 레퍼런스 5종을 읽는다** — `file-content-schema.md`, `shared-prompt-sections.md`, `xml-schema.md`, `work-activity-log.md`, `context-policy.md`.
|
|
200
|
+
3. **`orchestrator.md`의 절차를 그대로 수행한다.** 정본은 `orchestrator.md` 하나이며 축퇴용 별도 절차는 없습니다. STEP A~D, TASK DAG 스케줄링, 재시도, 컨텍스트 핸드오프, ref-cache 조립(STEP 1-1), 활동 로그 규칙이 **전부 동일하게** 적용됩니다.
|
|
201
|
+
4. **활동 로그**에 `ORCHESTRATOR_START` 직후 `ORCHESTRATOR_DEGRADED — reason=no-agent-tool`을 1회 기록합니다.
|
|
202
|
+
|
|
203
|
+
### 정상 경로와 다른 점 — 3가지뿐
|
|
204
|
+
|
|
205
|
+
| 항목 | 정상 | 축퇴 |
|
|
206
|
+
|------|------|------|
|
|
207
|
+
| 자식 spawn depth | 2 (orchestrator가 spawn) | **1** (Main Claude가 직접 spawn) |
|
|
208
|
+
| 게이트 처리 | orchestrator가 `<gate>` 반환 후 yield → Main Claude가 사용자에게 질의 | **Main Claude가 사용자에게 직접 질의** — `<gate>` XML·`SendMessage`·`TaskStop` 불필요 |
|
|
209
|
+
| 레퍼런스를 읽는 주체 | orchestrator | **Main Claude** |
|
|
210
|
+
|
|
211
|
+
그 외 산출물 형식, 로그 이벤트 체계, ref-cache 조립 규칙, 재개 판정은 모두 같습니다.
|
|
212
|
+
|
|
213
|
+
### 금지 사항
|
|
214
|
+
|
|
215
|
+
- **자식 역할을 인라인으로 대행하지 않는다.** 축퇴 모드에서도 specifier/planner/builder/verifier/committer는 반드시 별도 spawn한다. Main Claude가 직접 코드를 작성하거나 커밋하면 파이프라인의 역할 분리가 사라진다.
|
|
216
|
+
- `<ref-cache>` 없이 자식을 spawn하지 않는다 — 정상 경로와 동일하게 필수다.
|
|
217
|
+
|
|
218
|
+
### 재개
|
|
219
|
+
|
|
220
|
+
축퇴 모드로 진행 중이던 WORK를 재개할 때도 동일하다. Main Claude는 `works/{WORK_ID}/work_{WORK_ID}.log`의 마지막 이벤트로 재개 지점을 판정한다(§2 "재개 규칙"). 로그에 `ORCHESTRATOR_DEGRADED`가 있으면 그 WORK는 축퇴 모드로 시작됐다는 뜻이지만, 재개 시점의 환경이 바뀌었을 수 있으므로 **매번 orchestrator를 먼저 spawn해 다시 판정**한다.
|
|
@@ -2,7 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
에이전트 간 슬라이딩 윈도우 컨텍스트 전달 규칙.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 섹션 소비 매트릭스
|
|
8
|
+
|
|
9
|
+
orchestrator가 자식 spawn 시 `<ref-cache>`에 담을 섹션을 결정하는 기준표 → `xml-schema.md` § 4.
|
|
10
|
+
|
|
11
|
+
| § | 내용 | orch | spec | plan | build | verif | commit |
|
|
12
|
+
|---|------|:----:|:----:|:----:|:-----:|:-----:|:------:|
|
|
13
|
+
| 1 | 슬라이딩 윈도우 | ✅ | | | ✅ | ✅ | ✅ |
|
|
14
|
+
| 2 | Context-Handoff 4개 필드 | ✅ | | | ✅ | ✅ | ✅ |
|
|
15
|
+
| 3 | 파이프라인 단계별 입출력 | | | | ✅ | ✅ | ✅ |
|
|
16
|
+
| 4 | TASK 간 의존성 전달 | ✅ | | | ✅ | | |
|
|
17
|
+
| 5 | Orchestrator 디스패치 | ✅ | | | | | |
|
|
18
|
+
| 6 | Committer 재시도 | ✅ | | | | | |
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## § 1. 슬라이딩 윈도우
|
|
6
23
|
|
|
7
24
|
| 단계 거리 | 상세 레벨 | 규칙 |
|
|
8
25
|
|-----------|----------|------|
|
|
@@ -10,7 +27,7 @@
|
|
|
10
27
|
| 2단계 전 | `SUMMARY` | `what` 필드만, 1-3줄 |
|
|
11
28
|
| 3단계+ | `DROP` | 생략 |
|
|
12
29
|
|
|
13
|
-
## Context-Handoff 4개 필드
|
|
30
|
+
## § 2. Context-Handoff 4개 필드
|
|
14
31
|
|
|
15
32
|
| 필드 | FULL | SUMMARY | 내용 |
|
|
16
33
|
|------|:----:|:-------:|------|
|
|
@@ -19,7 +36,7 @@
|
|
|
19
36
|
| `caution` | ✅ | ❌ | 주의사항, 조건부 완료 (1-3줄) |
|
|
20
37
|
| `incomplete` | ✅ | ❌ | 미완료 항목 (1-2줄, 없으면 "None") |
|
|
21
38
|
|
|
22
|
-
## 파이프라인 단계별 입출력
|
|
39
|
+
## § 3. 파이프라인 단계별 입출력
|
|
23
40
|
|
|
24
41
|
### Builder
|
|
25
42
|
|
|
@@ -55,15 +72,15 @@
|
|
|
55
72
|
1. builder 성공 여부 확인 (context-handoff 상태 확인)
|
|
56
73
|
2. result.md 작성 + git commit
|
|
57
74
|
|
|
58
|
-
출력:
|
|
75
|
+
출력: `works/{WORK_ID}/TASK-XX_result.md` + task-result XML
|
|
59
76
|
|
|
60
|
-
## TASK 간 의존성 전달
|
|
77
|
+
## § 4. TASK 간 의존성 전달
|
|
61
78
|
|
|
62
79
|
- 직전 의존 TASK: context-handoff **FULL** (4개 필드 모두)
|
|
63
80
|
- 2단계 전: **SUMMARY** (what만)
|
|
64
81
|
- 3단계+: **DROP**
|
|
65
82
|
|
|
66
|
-
## Orchestrator 디스패치
|
|
83
|
+
## § 5. Orchestrator 디스패치
|
|
67
84
|
|
|
68
85
|
TASK DAG 실행 중 다음 자식(중첩 spawn)의 프롬프트를 구성하는 주체는 **orchestrator**다 — dispatch XML을 만들어 자식 spawn 프롬프트에 포함한다.
|
|
69
86
|
|
|
@@ -88,7 +105,7 @@ TASK DAG 실행 중 다음 자식(중첩 spawn)의 프롬프트를 구성하는
|
|
|
88
105
|
</dispatch>
|
|
89
106
|
```
|
|
90
107
|
|
|
91
|
-
## Committer 재시도
|
|
108
|
+
## § 6. Committer 재시도
|
|
92
109
|
|
|
93
110
|
1. 실패 원인: 검증 FAIL / 변경 파일 없음
|
|
94
111
|
2. builder에 재디스패치
|
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
파이프라인 산출물 파일 형식의 단일 정의 소스.
|
|
4
4
|
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 섹션 소비 매트릭스
|
|
8
|
+
|
|
9
|
+
orchestrator가 자식 spawn 시 `<ref-cache>`에 담을 섹션을 결정하는 기준표 → `xml-schema.md` § 4.
|
|
10
|
+
|
|
11
|
+
| § | 내용 | orch | spec | plan | build | verif | commit |
|
|
12
|
+
|---|------|:----:|:----:|:----:|:-----:|:-----:|:------:|
|
|
13
|
+
| — | 준수사항 (아래 표) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
14
|
+
| 0 | Requirement.md | | ✅ | ✅ | | | |
|
|
15
|
+
| 1 | PLAN.md | ✅ | | ✅ | | | |
|
|
16
|
+
| 2 | TASK-XX.md | | | ✅ | ✅ | ✅ | |
|
|
17
|
+
| 3 | TASK-XX_result.md | | | | ✅ | | ✅ |
|
|
18
|
+
| 4 | DECISIONS.md | ✅ | | | | | |
|
|
19
|
+
| 5 | 파일 이름 규칙 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
20
|
+
|
|
21
|
+
> "준수사항" 표는 § 번호가 없다. 모든 에이전트가 공통으로 필요로 하므로 이 파일을 전달할 때는 **항상 함께 싣고**, `sections` 속성에는 표기하지 않는다.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
5
25
|
## 준수사항
|
|
6
26
|
|
|
7
27
|
| 생성 파일 | 참조 섹션 | 위반 시 결과 |
|
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
# 공유 프롬프트 섹션
|
|
2
2
|
|
|
3
|
-
각 에이전트가
|
|
3
|
+
각 에이전트가 참조하는 공통 재사용 섹션.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 섹션 소비 매트릭스
|
|
8
|
+
|
|
9
|
+
orchestrator가 자식 spawn 시 `<ref-cache>`에 담을 섹션을 결정하는 기준표 → `xml-schema.md` § 4.
|
|
10
|
+
|
|
11
|
+
| § | 내용 | orch | spec | plan | build | verif | commit |
|
|
12
|
+
|---|------|:----:|:----:|:----:|:-----:|:-----:|:------:|
|
|
13
|
+
| 1 | 출력 언어 규칙 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
14
|
+
| 2 | 빌드 및 린트 명령 | | | | ✅ | ✅ | |
|
|
15
|
+
| 3 | WORK 및 TASK 파일 경로 패턴 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
16
|
+
| 4 | 파일 시스템 Discovery 스크립트 | ✅ | | | | | |
|
|
17
|
+
| 5 | Task Result XML 형식 | | | | ✅ | ✅ | ✅ |
|
|
18
|
+
| 6 | 자동결정 기록 관례 | ✅ | | | | | |
|
|
19
|
+
| 7 | PLAN.md 필수 메타 정보 | | | ✅ | | | |
|
|
20
|
+
| 8 | WORK-LIST.md 업데이트 규칙 | | ✅ | | | | ✅ |
|
|
21
|
+
| 9 | 로케일 감지 | ✅ | ✅ | | | | |
|
|
22
|
+
| 12 | Bash 명령 규칙 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
23
|
+
|
|
24
|
+
> § 10·§ 11은 존재하지 않는다(과거 삭제분). 기존 상호참조 호환을 위해 번호를 재사용하지 않는다.
|
|
4
25
|
|
|
5
26
|
---
|
|
6
27
|
|
|
@@ -126,7 +147,7 @@ works/{WORK_ID}/
|
|
|
126
147
|
|
|
127
148
|
## § 7. PLAN.md 필수 메타 정보 — 7개 필드
|
|
128
149
|
|
|
129
|
-
→ `
|
|
150
|
+
→ `file-content-schema.md` § 1 참조
|
|
130
151
|
|
|
131
152
|
| 필드 | 필수 | 설명 |
|
|
132
153
|
|------|------|------|
|
|
@@ -2,25 +2,42 @@
|
|
|
2
2
|
|
|
3
3
|
`works/{WORK_ID}/work_{WORK_ID}.log`에 실행 이벤트를 기록.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
---
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## 섹션 소비 매트릭스
|
|
8
|
+
|
|
9
|
+
orchestrator가 자식 spawn 시 `<ref-cache>`에 담을 섹션을 결정하는 기준표 → `xml-schema.md` § 4.
|
|
10
|
+
|
|
11
|
+
| § | 내용 | orch | spec | plan | build | verif | commit |
|
|
12
|
+
|---|------|:----:|:----:|:----:|:-----:|:-----:|:------:|
|
|
13
|
+
| 1 | 규칙 | ✅ | | | | | |
|
|
14
|
+
| 2 | 형식 | ✅ | | | | | ✅ |
|
|
15
|
+
| 3 | 이벤트 체계 | ✅ | | | | | ✅ |
|
|
16
|
+
|
|
17
|
+
> committer는 마지막 TASK 판정을 위해 로그를 **읽기만** 한다 — 기록 주체는 orchestrator뿐(§ 1).
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## § 1. 규칙
|
|
22
|
+
|
|
23
|
+
1. **기록 주체**: **orchestrator 역할을 수행하는 주체**. 정상 경로에서는 orchestrator 에이전트이고, 축퇴 모드(→ `xml-schema.md` § 8)에서는 그 역할을 넘겨받은 Main Claude다. 어느 쪽이든 자식의 spawn/완료를 `STAGE_START`/`STAGE_DONE`으로 기록한다.
|
|
8
24
|
2. **타임스탬프**: Bash로 `date -u +"%Y-%m-%dT%H:%M:%SZ"` 실행하여 실제 UTC 시간 획득. 더미 값 사용 금지.
|
|
9
25
|
3. **기록 방법**: Bash `echo` 로 추가.
|
|
10
26
|
4. **`STAGE_DONE`은 게이트 통과 후에 기록한다.** 해당 단계에 게이트(`<gate type="stage">` 또는 `<gate type="decision">`)가 있는 경우, Main Claude/사용자의 승인·결정으로 게이트가 해소(RESOLVED)된 시점에만 `STAGE_DONE`을 남긴다. 게이트 대기 중에는 `GATE_WAIT`/`DECISION_WAIT`만 기록되고, `STAGE_DONE`은 아직 기록되지 않은 상태로 남는다.
|
|
11
27
|
- **근거(재개 판정)**: 파이프라인이 중단 후 재개(resume)될 때 orchestrator는 로그의 마지막 이벤트로 재개 지점을 판정한다. 특정 단계에 `STAGE_START`만 있고 `STAGE_DONE`이 없다면 "그 단계의 게이트가 아직 승인/결정되지 않았다"는 뜻이므로, orchestrator는 다음 단계로 건너뛰지 않고 동일 게이트를 다시 제시해야 한다. `STAGE_DONE`을 게이트 통과 이전에 기록하면 재개 시 미승인 게이트를 건너뛰는 사고로 이어진다.
|
|
12
28
|
|
|
13
|
-
## 형식
|
|
29
|
+
## § 2. 형식
|
|
14
30
|
|
|
15
31
|
```
|
|
16
32
|
[YYYY-MM-DDTHH:MM:SSZ] EVENT — description
|
|
17
33
|
```
|
|
18
34
|
|
|
19
|
-
## 이벤트 체계 (orchestrator 기록)
|
|
35
|
+
## § 3. 이벤트 체계 (orchestrator 기록)
|
|
20
36
|
|
|
21
37
|
| 이벤트 | 기록 시점 | 예시 |
|
|
22
38
|
|--------|----------|------|
|
|
23
39
|
| `ORCHESTRATOR_START` | orchestrator 실행 시작 | `ORCHESTRATOR_START — WORK-NN orchestrator started` |
|
|
40
|
+
| `ORCHESTRATOR_DEGRADED` | 축퇴 모드 진입 — Main Claude가 orchestrator 역할을 넘겨받음. `ORCHESTRATOR_START` 직후 1회 기록 | `ORCHESTRATOR_DEGRADED — reason=no-agent-tool` |
|
|
24
41
|
| `STAGE_START` | 자식 에이전트(specifier/planner/builder/verifier/committer) spawn 직전 | `STAGE_START — stage=specifier` |
|
|
25
42
|
| `GATE_WAIT` | `<gate type="stage">`에서 정지, Main Claude 승인 대기 | `GATE_WAIT — stage=specifier` |
|
|
26
43
|
| `DECISION_WAIT` | `<gate type="decision">` 또는 자식의 `<needs-decision>` 수신 후 결정 대기 | `DECISION_WAIT — stage=planner` |
|
|
@@ -30,4 +47,4 @@
|
|
|
30
47
|
|
|
31
48
|
- `stage` 값: `specifier`/`planner`/`builder`/`verifier`/`committer`.
|
|
32
49
|
- `by` 값: `user`/`auto`. `<decision>`(§ 7, `xml-schema.md`)의 `by` 속성과 동일한 값 체계를 사용.
|
|
33
|
-
- 확정된 결정의 상세 내용(배경/선택지/권고안/확정값)은 로그가 아니라 `works/{WORK_ID}/DECISIONS.md`에
|
|
50
|
+
- 확정된 결정의 상세 내용(배경/선택지/권고안/확정값)은 로그가 아니라 `works/{WORK_ID}/DECISIONS.md`에 orchestrator가 기록한다. 로그의 `DECISION` 이벤트는 "언제·누가 결정했는지"만 남긴다.
|
package/references/xml-schema.md
CHANGED
|
@@ -4,20 +4,36 @@ uc-taskmanager 에이전트용 XML 통신 형식 정의.
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## 섹션 소비 매트릭스
|
|
8
|
+
|
|
9
|
+
orchestrator가 자식 spawn 시 `<ref-cache>`에 담을 섹션을 결정하는 기준표 → § 4.
|
|
10
|
+
|
|
11
|
+
| § | 내용 | orch | spec | plan | build | verif | commit |
|
|
12
|
+
|---|------|:----:|:----:|:----:|:-----:|:-----:|:------:|
|
|
13
|
+
| 1 | Dispatch 형식 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
14
|
+
| 2 | Task Result 형식 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
15
|
+
| 3 | Context-Handoff 요소 | ✅ | | | ✅ | ✅ | ✅ |
|
|
16
|
+
| 4 | ref-cache 프로토콜 | ✅ | | | | | |
|
|
17
|
+
| 5 | Gate 요소 | ✅ | | | | | |
|
|
18
|
+
| 6 | needs-decision 요소 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
19
|
+
| 7 | decision 요소 | ✅ | | | | | |
|
|
20
|
+
| 8 | capability-degraded 요소 | ✅ | | | | | |
|
|
21
|
+
|
|
22
|
+
> § 4·§ 5·§ 7·§ 8은 **orchestrator 전용**이다. ref-cache 생성(§ 4), 게이트 발행(§ 5), 결정 확정(§ 7)은 모두 orchestrator의 책임이며 자식 에이전트는 수행하지 않는다. 자식에게 필요한 ref-cache 소비 규칙은 각 에이전트 정의의 STARTUP 절에 인라인으로 기술되어 있다.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
7
26
|
> **디스패처 라벨**: dispatch를 발신하고 task-result를 수신하는 디스패처 역할은 **orchestrator**가 수행한다. 아래 §1/§2의 "디스패처"는 모두 orchestrator를 가리킨다.
|
|
8
27
|
|
|
9
|
-
## 1. Dispatch 형식 (orchestrator → 수신자)
|
|
28
|
+
## § 1. Dispatch 형식 (orchestrator → 수신자)
|
|
10
29
|
|
|
11
30
|
```xml
|
|
12
31
|
<dispatch to="{receiver}" work="{WORK_ID}" task="{TASK_ID}">
|
|
13
|
-
<ref-cache> <!--
|
|
14
|
-
<ref key="shared-prompt-sections">{
|
|
15
|
-
<ref key="
|
|
16
|
-
|
|
17
|
-
<ref key="context-policy">{파일 내용}</ref>
|
|
18
|
-
<ref key="work-activity-log">{파일 내용}</ref>
|
|
32
|
+
<ref-cache> <!-- 필수 — § 4 참조 -->
|
|
33
|
+
<ref key="shared-prompt-sections" sections="1,3,12">{해당 섹션 원문}</ref>
|
|
34
|
+
<ref key="xml-schema" sections="1,2,6">{해당 섹션 원문}</ref>
|
|
35
|
+
<!-- 수신자에게 필요한 섹션만 (§ 4 조립 절차 참조) -->
|
|
19
36
|
</ref-cache>
|
|
20
|
-
<references-dir>{references 디렉토리 절대 경로}</references-dir>
|
|
21
37
|
<context>
|
|
22
38
|
<project>{프로젝트 이름}</project>
|
|
23
39
|
<language>{lang_code}</language>
|
|
@@ -32,7 +48,6 @@ uc-taskmanager 에이전트용 XML 통신 형식 정의.
|
|
|
32
48
|
<previous-results>
|
|
33
49
|
<result task="{TASK_ID}" status="{PASS|FAIL|SKIP}">{요약}</result>
|
|
34
50
|
</previous-results>
|
|
35
|
-
<cache-hint sections="{section1},{section2}"/>
|
|
36
51
|
</dispatch>
|
|
37
52
|
```
|
|
38
53
|
|
|
@@ -41,9 +56,11 @@ uc-taskmanager 에이전트용 XML 통신 형식 정의.
|
|
|
41
56
|
| `to` | builder, verifier, committer, planner, specifier |
|
|
42
57
|
| `task` | `TASK-NN` — WORK 접두사 포함 금지 |
|
|
43
58
|
|
|
59
|
+
> `<ref-cache>`는 **필수**다. orchestrator는 이것 없이 자식을 spawn하지 않는다 — 자식이 레퍼런스를 디스크에서 다시 읽게 되어 ref-cache가 무력화된다.
|
|
60
|
+
|
|
44
61
|
---
|
|
45
62
|
|
|
46
|
-
## 2. Task Result 형식 (수신자 → orchestrator)
|
|
63
|
+
## § 2. Task Result 형식 (수신자 → orchestrator)
|
|
47
64
|
|
|
48
65
|
```xml
|
|
49
66
|
<task-result work="{WORK_ID}" task="{TASK_ID}" agent="{agent}" status="{PASS|FAIL}">
|
|
@@ -55,19 +72,14 @@ uc-taskmanager 에이전트용 XML 통신 형식 정의.
|
|
|
55
72
|
<check name="{type}" status="{PASS|FAIL|N/A}">{출력}</check>
|
|
56
73
|
</verification>
|
|
57
74
|
<notes>{메모}</notes>
|
|
58
|
-
<ref-cache> <!-- 선택사항 -->
|
|
59
|
-
<ref key="shared-prompt-sections">{파일 내용}</ref>
|
|
60
|
-
<ref key="file-content-schema">{파일 내용}</ref>
|
|
61
|
-
<ref key="xml-schema">{파일 내용}</ref>
|
|
62
|
-
<ref key="context-policy">{파일 내용}</ref>
|
|
63
|
-
<ref key="work-activity-log">{파일 내용}</ref>
|
|
64
|
-
</ref-cache>
|
|
65
75
|
</task-result>
|
|
66
76
|
```
|
|
67
77
|
|
|
78
|
+
> task-result에는 `<ref-cache>`를 **포함하지 않는다**. 캐시의 단일 소스는 orchestrator이며(§ 4), 자식이 전달받은 내용을 되돌려주는 것은 순수한 토큰 낭비다.
|
|
79
|
+
|
|
68
80
|
---
|
|
69
81
|
|
|
70
|
-
## 3. Context-Handoff 요소
|
|
82
|
+
## § 3. Context-Handoff 요소
|
|
71
83
|
|
|
72
84
|
```xml
|
|
73
85
|
<context-handoff from="{agent}" detail-level="{FULL|SUMMARY|DROP}">
|
|
@@ -86,43 +98,76 @@ uc-taskmanager 에이전트용 XML 통신 형식 정의.
|
|
|
86
98
|
|
|
87
99
|
---
|
|
88
100
|
|
|
89
|
-
## 4. ref-cache
|
|
101
|
+
## § 4. ref-cache 프로토콜 (orchestrator 전용)
|
|
102
|
+
|
|
103
|
+
### 원칙
|
|
90
104
|
|
|
91
|
-
|
|
105
|
+
레퍼런스 파일을 읽는 주체는 **orchestrator 하나뿐**이다. orchestrator는 기동 시 1회 읽고, 자식을 중첩 spawn할 때마다 **그 자식에게 필요한 섹션만** 잘라 `<ref-cache>`로 전달한다. 자식은 디스크를 읽지 않는다.
|
|
106
|
+
|
|
107
|
+
| 주체 | 행위 |
|
|
108
|
+
|------|------|
|
|
109
|
+
| orchestrator | 레퍼런스 5종 읽기(1회) → 각 파일의 **섹션 소비 매트릭스** 파싱 → 자식별 `<ref-cache>` 조립 → dispatch에 필수 포함 |
|
|
110
|
+
| 자식 에이전트 | `<ref-cache>` 내용만 사용. `{REFERENCES_DIR}` 하위 파일에 대한 `Read`/`Glob`/`Grep` **금지** |
|
|
92
111
|
|
|
93
112
|
### 구조
|
|
94
113
|
|
|
95
114
|
```xml
|
|
96
115
|
<ref-cache>
|
|
97
|
-
<ref key="{확장자 없는 파일명}">{
|
|
116
|
+
<ref key="{확장자 없는 파일명}" sections="{쉼표 구분 § 번호}">{해당 섹션 원문}</ref>
|
|
98
117
|
...
|
|
99
118
|
</ref-cache>
|
|
100
119
|
```
|
|
101
120
|
|
|
102
|
-
|
|
|
103
|
-
|
|
104
|
-
| `<ref-cache>` |
|
|
105
|
-
| `<ref key="...">` | — |
|
|
121
|
+
| 요소/속성 | 필수 | 설명 |
|
|
122
|
+
|-----------|:----:|------|
|
|
123
|
+
| `<ref-cache>` | ✅ | dispatch에 항상 포함. 생략 금지. |
|
|
124
|
+
| `<ref key="...">` | — | 레퍼런스 파일 1개당 1개. `key`는 확장자 없는 파일명. |
|
|
125
|
+
| `sections="..."` | ✅ | 이 `<ref>`에 담긴 § 번호 목록 (예: `"1,3,12"`). 자식의 자기검증용. |
|
|
126
|
+
|
|
127
|
+
- `<ref>` 본문에는 **`## § N.` 헤딩을 그대로 보존**한 원문을 넣는다 — 문서 내 "→ `xml-schema.md` § 6 참조" 같은 상호참조가 그대로 해소되어야 한다.
|
|
128
|
+
- § 번호가 없는 도입부 표(예: `file-content-schema.md`의 "준수사항")는 해당 파일 전달 시 항상 함께 싣고 `sections`에는 표기하지 않는다.
|
|
106
129
|
|
|
107
130
|
### 인식되는 키
|
|
108
131
|
|
|
109
|
-
| 키 | 대응 파일 |
|
|
110
|
-
|
|
111
|
-
| `shared-prompt-sections` | `{REFERENCES_DIR}/shared-prompt-sections.md` |
|
|
112
|
-
| `file-content-schema` | `{REFERENCES_DIR}/file-content-schema.md` |
|
|
113
|
-
| `xml-schema` | `{REFERENCES_DIR}/xml-schema.md` |
|
|
114
|
-
| `context-policy` | `{REFERENCES_DIR}/context-policy.md` |
|
|
115
|
-
| `work-activity-log` | `{REFERENCES_DIR}/work-activity-log.md` |
|
|
132
|
+
| 키 | 대응 파일 | 섹션 범위 |
|
|
133
|
+
|-----|-----------|----------|
|
|
134
|
+
| `shared-prompt-sections` | `{REFERENCES_DIR}/shared-prompt-sections.md` | § 1~9, § 12 |
|
|
135
|
+
| `file-content-schema` | `{REFERENCES_DIR}/file-content-schema.md` | 준수사항, § 0~5 |
|
|
136
|
+
| `xml-schema` | `{REFERENCES_DIR}/xml-schema.md` | § 1~7 |
|
|
137
|
+
| `context-policy` | `{REFERENCES_DIR}/context-policy.md` | § 1~6 |
|
|
138
|
+
| `work-activity-log` | `{REFERENCES_DIR}/work-activity-log.md` | § 1~3 |
|
|
139
|
+
|
|
140
|
+
### 조립 절차 (orchestrator)
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
1. 대상 자식(specifier/planner/builder/verifier/committer)을 확정한다.
|
|
144
|
+
2. 읽어둔 레퍼런스 5종 각각의 "섹션 소비 매트릭스" 표에서 해당 자식 열이 ✅인 행을 모은다.
|
|
145
|
+
표를 끝까지 훑어 ✅ 행을 하나도 빠뜨리지 않는다.
|
|
146
|
+
3. ✅ 행이 하나도 없는 파일은 <ref> 자체를 생성하지 않는다.
|
|
147
|
+
4. ✅ 행이 있는 파일마다 <ref>를 정확히 1개씩만 만든다.
|
|
148
|
+
같은 key로 두 번 넣지 않으며, sections에 ✅ 번호를 빠짐없이 나열한다.
|
|
149
|
+
본문은 해당 § 원문을 헤딩째 발췌한다.
|
|
150
|
+
5. 조립된 <ref-cache>를 dispatch XML 최상단에 넣어 자식 spawn 프롬프트에 포함한다.
|
|
151
|
+
6. spawn 직전 자체 점검: key 중복이 없고, key 구성·sections 값이 매트릭스와 일치하는지 대조한다.
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### 조립 불변식
|
|
155
|
+
|
|
156
|
+
| 규칙 | 위반 시 |
|
|
157
|
+
|------|---------|
|
|
158
|
+
| 파일 1개당 `<ref>` 1개 | 같은 내용이 두 번 실려 토큰 낭비 |
|
|
159
|
+
| `sections`에 매트릭스 ✅ 를 빠짐없이 | 자식이 필요한 내용을 받지 못함 |
|
|
160
|
+
| `sections` 값 = 실제 담긴 § 목록 | 자식의 자기검증이 무의미해짐 |
|
|
116
161
|
|
|
117
|
-
###
|
|
162
|
+
### 내용 부족 시 처리 (엄격 모드)
|
|
118
163
|
|
|
119
|
-
-
|
|
120
|
-
- ref-cache
|
|
121
|
-
-
|
|
164
|
+
- 자식은 어떤 경우에도 레퍼런스 파일을 디스크에서 읽지 않는다. **폴백 경로는 없다.**
|
|
165
|
+
- 작업에 필요한 내용이 `<ref-cache>`에 없으면 `<needs-decision>`(§ 6)으로 부족한 `key`·내용을 명시해 orchestrator에 상향하고 종료한다.
|
|
166
|
+
- orchestrator는 누락분을 보충한 `<ref-cache>`로 해당 자식을 재spawn한다. 이는 매트릭스 배분이 실제 필요와 어긋났다는 신호이므로, 반복되면 해당 파일의 섹션 소비 매트릭스를 수정한다.
|
|
122
167
|
|
|
123
168
|
---
|
|
124
169
|
|
|
125
|
-
## 5. Gate 요소 (orchestrator → Main Claude)
|
|
170
|
+
## § 5. Gate 요소 (orchestrator → Main Claude)
|
|
126
171
|
|
|
127
172
|
`<gate>`는 orchestrator가 자율 실행을 일시 정지하고 Main Claude(및 사용자)의 승인 또는 결정을 요청할 때 반환하는 정지 신호입니다. orchestrator는 `<gate>`를 반환한 뒤 Main Claude의 응답(승인 또는 `<decision>`)이 돌아올 때까지 재개하지 않습니다.
|
|
128
173
|
|
|
@@ -160,7 +205,7 @@ uc-taskmanager 에이전트용 XML 통신 형식 정의.
|
|
|
160
205
|
|
|
161
206
|
---
|
|
162
207
|
|
|
163
|
-
## 6. needs-decision 요소 (자식 에이전트 → orchestrator)
|
|
208
|
+
## § 6. needs-decision 요소 (자식 에이전트 → orchestrator)
|
|
164
209
|
|
|
165
210
|
`<needs-decision>`은 자식 에이전트(builder/verifier 등)가 구현 중 스스로 결정할 수 없는 사항을 발견했을 때, task-result와 함께(또는 대신) orchestrator에 상향 보고하는 신호입니다. Main Claude로 직접 올라가지 않고 먼저 orchestrator가 받는다는 점에서 `<gate type="decision">`과 구분됩니다.
|
|
166
211
|
|
|
@@ -184,11 +229,11 @@ uc-taskmanager 에이전트용 XML 통신 형식 정의.
|
|
|
184
229
|
- orchestrator는 `<needs-decision>` 수신 시 자동 결정 가능 여부를 판단한다.
|
|
185
230
|
- 자동 결정 가능 → `<decision by="auto">`(§ 7)로 확정하고 자식 작업을 재개시킴.
|
|
186
231
|
- 자동 결정 불가 → `<gate type="decision">`(§ 5)으로 승격하여 Main Claude에 전달.
|
|
187
|
-
- 어느 경로든 결정 내용은 `works/{WORK_ID}/DECISIONS.md`에
|
|
232
|
+
- 어느 경로든 결정 내용은 **orchestrator가** `works/{WORK_ID}/DECISIONS.md`에 기록한다. 자식 에이전트는 DECISIONS.md를 직접 쓰지 않으므로 그 포맷을 알 필요가 없다.
|
|
188
233
|
|
|
189
234
|
---
|
|
190
235
|
|
|
191
|
-
## 7. decision 요소 (확정 결정 기록)
|
|
236
|
+
## § 7. decision 요소 (확정 결정 기록)
|
|
192
237
|
|
|
193
238
|
`<decision>`은 게이트(§ 5) 또는 needs-decision(§ 6)에 대해 내려진 확정 결정을 기록하는 요소입니다. 사용자 승인분(`by="user"`)과 orchestrator 자동결정분(`by="auto"`)이 동일한 형식을 공유합니다.
|
|
194
239
|
|
|
@@ -215,3 +260,33 @@ uc-taskmanager 에이전트용 XML 통신 형식 정의.
|
|
|
215
260
|
| `by` | `user`(사용자 승인) / `auto`(orchestrator 자동결정) |
|
|
216
261
|
|
|
217
262
|
- orchestrator는 `<decision>` 확정 즉시 `works/{WORK_ID}/DECISIONS.md`의 해당 항목을 `PENDING → RESOLVED`로 갱신하고, 활동 로그에 `DECISION` 이벤트를 기록한다 → `work-activity-log.md` 참조.
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## § 8. capability-degraded 요소 (orchestrator → Main Claude)
|
|
267
|
+
|
|
268
|
+
`<capability-degraded>`는 orchestrator가 **자신의 실행 환경이 파이프라인을 수행할 수 없음**을 감지했을 때, 아무 작업도 하지 않고 즉시 반환하는 신호입니다.
|
|
269
|
+
|
|
270
|
+
```xml
|
|
271
|
+
<capability-degraded reason="no-agent-tool">
|
|
272
|
+
<detail>서브에이전트에 Agent 도구가 주입되지 않아 중첩 spawn 불가</detail>
|
|
273
|
+
</capability-degraded>
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
| 속성/요소 | 값 |
|
|
277
|
+
|-----------|-----|
|
|
278
|
+
| `reason` | `no-agent-tool` — 중첩 spawn용 `Agent` 도구 부재 |
|
|
279
|
+
| `<detail>` | 사람이 읽을 수 있는 사유 1줄 |
|
|
280
|
+
|
|
281
|
+
### 발생 조건
|
|
282
|
+
|
|
283
|
+
일부 CLI 버전·환경에서 서브에이전트에 `Agent` 도구가 주입되지 않아 자식 중첩 spawn이 불가능한 경우. orchestrator는 기동 직후(STEP 0, 레퍼런스를 읽기 전) 이를 판정한다.
|
|
284
|
+
|
|
285
|
+
### 불변식
|
|
286
|
+
|
|
287
|
+
- orchestrator는 이 신호를 반환하기 전에 **어떤 산출물도 만들지 않는다** — WORK 폴더, Requirement.md, 활동 로그 모두 생성 금지.
|
|
288
|
+
- orchestrator는 자식 역할을 **인라인으로 대행하지 않는다.** 대행하면 WORK가 완료된 것처럼 보이지만 역할 분리와 검증 독립성이 사라진 채로 끝나며, 오류가 나지 않아 발견되지 않는다.
|
|
289
|
+
|
|
290
|
+
### Main Claude의 처리
|
|
291
|
+
|
|
292
|
+
Main Claude는 이 신호를 받으면 축퇴 모드로 전환해 **자신이 orchestrator 역할을 수행**한다. 절차의 정본은 `orchestrator.md` 그대로이며, 자식이 depth=1로 뜨는 것만 다르다 → `agent-flow.md` 축퇴 모드 절 참조.
|
|
@@ -54,9 +54,24 @@ Main Claude는 `orchestrator` 에이전트 하나만 spawn합니다. specifier/p
|
|
|
54
54
|
2. 게이트/의사결정 정지 없이 orchestrator가 전체 파이프라인을 완주하고 최종 요약(`## 자동 결정 사항` 포함)을 반환한다.
|
|
55
55
|
3. 반환된 최종 요약을 사용자에게 제시한다. (파킹 상태가 아니므로 TaskStop 불필요.)
|
|
56
56
|
|
|
57
|
+
## 축퇴 모드 (중첩 spawn 미지원 환경)
|
|
58
|
+
|
|
59
|
+
orchestrator가 `<capability-degraded reason="no-agent-tool">`을 반환하면, 그 환경은 서브에이전트에 `Agent` 도구를 주지 않아 중첩 spawn이 불가능한 상태입니다(CLI 버전에 따라 발생). orchestrator는 아무 산출물도 만들지 않고 즉시 반환하므로 디스크에는 아무것도 없습니다.
|
|
60
|
+
|
|
61
|
+
이때 Main Claude가 **orchestrator 역할을 넘겨받습니다**:
|
|
62
|
+
|
|
63
|
+
1. 사용자에게 1줄 알린다 — "중첩 spawn 미지원 환경 — Main Claude가 직접 오케스트레이션합니다". 승인을 기다리지 않고 진행.
|
|
64
|
+
2. `{REFERENCES_DIR}/orchestrator.md`와 레퍼런스 5종을 읽는다.
|
|
65
|
+
3. `orchestrator.md` 절차를 그대로 수행한다 — specifier/planner/builder/verifier/committer를 **직접 spawn**(depth=1)하고, ref-cache 조립·활동 로그·TASK DAG·재시도 규칙을 동일하게 적용한다.
|
|
66
|
+
4. 활동 로그에 `ORCHESTRATOR_DEGRADED — reason=no-agent-tool`을 기록한다.
|
|
67
|
+
5. 게이트는 `<gate>` XML/`SendMessage` 없이 사용자에게 **직접** 질의한다.
|
|
68
|
+
|
|
69
|
+
→ 상세: `agent-flow.md` § 7
|
|
70
|
+
|
|
57
71
|
## ⚠️ CRITICAL: 에이전트 Spawn 규칙
|
|
58
72
|
|
|
59
|
-
- Main Claude가 spawn하는 에이전트는 **orchestrator 하나뿐**이다. Main Claude가 직접 코드 구현, 파일 생성, git 명령 실행 또는 orchestrator의 작업을 수행하면 안 된다.
|
|
73
|
+
- **정상 경로**에서 Main Claude가 spawn하는 에이전트는 **orchestrator 하나뿐**이다. Main Claude가 직접 코드 구현, 파일 생성, git 명령 실행 또는 orchestrator의 작업을 수행하면 안 된다.
|
|
74
|
+
- **축퇴 모드**에서는 Main Claude가 자식 5종을 직접 spawn한다. 단 이 경우에도 **자식 역할을 스스로 대행하지는 않는다** — 반드시 각 에이전트를 spawn해야 한다.
|
|
60
75
|
- 게이트 재개는 항상 **agentId** 기준(SendMessage/TaskStop 모두)으로 한다 — name 재사용에 의한 오배달을 방지한다.
|
|
61
76
|
|
|
62
77
|
## Arguments
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# ref-cache 프로토콜
|
|
2
|
-
|
|
3
|
-
## 개요
|
|
4
|
-
|
|
5
|
-
ref-cache는 파이프라인 내 서브에이전트 호출 간 중복 파일 읽기를 방지하는 메커니즘입니다.
|
|
6
|
-
레퍼런스 파일이 매번 디스크에서 다시 읽히는 대신 `<ref-cache>` XML 요소를 통해 에이전트 간에 전달됩니다.
|
|
7
|
-
|
|
8
|
-
## 프로토콜 (4단계)
|
|
9
|
-
|
|
10
|
-
1. 수신한 dispatch XML에 `<ref-cache>`가 있는지 **확인**
|
|
11
|
-
2. 각 필수 레퍼런스 파일에 대해:
|
|
12
|
-
- ref-cache에 있으면 → **파일 읽기 건너뛰기**, 캐시된 내용 사용
|
|
13
|
-
- ref-cache에 없으면 → `{REFERENCES_DIR}/{filename}.md`에서 읽고 ref-cache에 추가
|
|
14
|
-
3. 작업 완료 시, 반환하는 task-result XML에 병합된 `<ref-cache>` 포함
|
|
15
|
-
4. **하위 호환성**: dispatch에 `<ref-cache>`가 없으면 모든 레퍼런스 파일을 정상적으로 읽기 (기존 동작)
|
|
16
|
-
|
|
17
|
-
## ref-cache XML 형식
|
|
18
|
-
|
|
19
|
-
전체 스키마는 `xml-schema.md` § 4 참조.
|
|
20
|
-
|
|
21
|
-
```xml
|
|
22
|
-
<ref-cache>
|
|
23
|
-
<ref key="file-content-schema">...내용...</ref>
|
|
24
|
-
<ref key="shared-prompt-sections">...내용...</ref>
|
|
25
|
-
<!-- 로딩된 레퍼런스 파일당 하나의 <ref> -->
|
|
26
|
-
</ref-cache>
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## 체인 전파
|
|
30
|
-
|
|
31
|
-
파이프라인에서 ref-cache가 에이전트 간에 어떻게 흐르는지는 `agent-flow.md` § ref-cache Chain Propagation 참조.
|