makdoong2-team 1.4.0 → 1.4.2

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/README.md CHANGED
@@ -121,25 +121,74 @@ makdoong2-team doctor # 설치 진단
121
121
 
122
122
  ### 모델 정책
123
123
 
124
- 빌트인 primary 허용 목록은 `github-copilot/*` 와 `local/*` 브랜드 40개다 (전체 목록: `src/model-fallback-policy.ts` `DEFAULT_ALLOWED_PRIMARIES`). fallback **항상 primary 보다 낮은 tier** 여야 한다 (`low < medium < high < max`).
124
+ 체인 하나는 `primary` 1개와 **tier 낮은** `fallbacks` 이뤄진다. 7개 에이전트 전부 아래 빌트인 기본값을 쓴다.
125
+
126
+ ```jsonc
127
+ // src/model-fallback-policy.ts 의 POLICIES — 7개 에이전트가 모두 동일하다
128
+ "makdoong2-engineer": {
129
+ "primary": { "id": "github-copilot/gpt-5.6-luna", "variant": "xhigh", "tier": "medium" },
130
+ "fallbacks": [{ "id": "github-copilot/claude-haiku-4.5", "tier": "low" }]
131
+ }
132
+ ```
133
+
134
+ | 필드 | 의미 | 설정 키 |
135
+ |---|---|---|
136
+ | `id` | `provider/model`. primary 는 허용 목록 안이어야 한다 — 빌트인 `github-copilot/*` · `local/*` 40개 (`DEFAULT_ALLOWED_PRIMARIES`) + `allowed_primaries` 확장분 | `agents.<agent>.model`, `fallback_models[].id` |
137
+ | `variant` | 추론 강도 `low` · `medium` · `high` · `xhigh` · `max`. **primary 에만** 쓰이고 opencode agent 설정으로 그대로 주입된다 | `agents.<agent>.variant` |
138
+ | `tier` | 폴백 순서 invariant 전용 등급 (`low < medium < high < max`). fallback 은 **항상 primary 보다 낮아야** 한다 | `fallback_models[].tier` |
139
+
140
+ primary 의 `tier` 는 설정으로 바꿀 수 없다 — 빌트인 값이 유지되고, 빌트인에 없는 새 에이전트는 `medium` 이 된다.
141
+
142
+ 오버라이드 예시:
125
143
 
126
144
  ```jsonc
127
145
  {
128
146
  "model_policy": {
147
+ // 빌트인 허용 목록에 없는 primary 를 쓸 때만 필요하다 (추가 전용 — 빈 배열은 "추가 없음")
129
148
  "allowed_primaries": ["custom-provider/custom-model"]
130
149
  },
131
150
  "agents": {
151
+ // primary · variant · fallback 을 모두 지정
132
152
  "makdoong2-engineer": {
133
153
  "model": "github-copilot/claude-opus-4.8",
154
+ "variant": "high",
134
155
  "fallback_models": [
135
156
  { "id": "github-copilot/claude-haiku-4.5", "tier": "low" }
136
157
  ]
137
- }
158
+ },
159
+
160
+ // model 만 적으면 variant 와 fallback 체인은 빌트인 값을 승계한다
161
+ "makdoong2-planner": { "model": "github-copilot/gpt-5.6-sol" },
162
+
163
+ // variant 만 낮추고 싶어도 model 은 반드시 함께 적는다 — model 없는 항목은 통째로 무시된다
164
+ "makdoong2-verifier": { "model": "github-copilot/gpt-5.6-luna", "variant": "medium" }
138
165
  }
139
166
  }
140
167
  ```
141
168
 
142
- `makdoong2-team validate` 로 위반 여부와 최종 체인을 미리 확인할 수 있다. 위반 플러그인은 defaults 로 롤백하고 stderr 에 경고만 남긴다 — 설정 오류로 워크플로우가 죽지 않는다.
169
+ `makdoong2-team validate` 로 위반 여부와 최종 체인을 미리 확인할 수 있다. 설정의 실제 출력이다.
170
+
171
+ ```console
172
+ $ makdoong2-team validate
173
+ [makdoong2-team] validate — ~/.config/opencode/makdoong2-team.json
174
+ ✓ JSON parses
175
+ ✓ policy invariants pass (primary allow-list + fallback tier ordering)
176
+ ✓ overrides applied for: makdoong2-engineer, makdoong2-planner, makdoong2-verifier
177
+ ✓ extra allowed primaries: custom-provider/custom-model
178
+
179
+ Resolved chain (primary → fallbacks):
180
+ makdoong2-team-leader github-copilot/gpt-5.6-luna (medium) → github-copilot/claude-haiku-4.5 (low)
181
+ makdoong2-analyzer github-copilot/gpt-5.6-luna (medium) → github-copilot/claude-haiku-4.5 (low)
182
+ makdoong2-researcher github-copilot/gpt-5.6-luna (medium) → github-copilot/claude-haiku-4.5 (low)
183
+ makdoong2-planner github-copilot/gpt-5.6-sol (medium) → github-copilot/claude-haiku-4.5 (low)
184
+ makdoong2-engineer github-copilot/claude-opus-4.8 (medium) → github-copilot/claude-haiku-4.5 (low)
185
+ makdoong2-publisher github-copilot/gpt-5.6-luna (medium) → github-copilot/claude-haiku-4.5 (low)
186
+ makdoong2-verifier github-copilot/gpt-5.6-luna (medium) → github-copilot/claude-haiku-4.5 (low)
187
+
188
+ [makdoong2-team] validate: OK ✓
189
+ ```
190
+
191
+ 위반 시 플러그인은 defaults 로 롤백하고 stderr 에 경고만 남긴다 — 설정 오류로 워크플로우가 죽지 않는다.
143
192
 
144
193
  ### 로깅
145
194
 
@@ -180,7 +229,7 @@ makdoong2-team doctor # 설치 진단
180
229
  2. `src/opencode-plugin.ts` — `STAGE_ORDER` 배열에 삽입
181
230
  3. `stages/NN-<name>.md` — 신규 spec 작성
182
231
  4. `agents/makdoong2-<role>.md` + `gates/verify.sh` (+ 전용 `stage*-verify.sh`)
183
- 5. README 매핑표 · `AGENTS.md` sealed workflow 규약 갱신
232
+ 5. README 매핑표 · `CLAUDE.md` sealed workflow 규약 갱신
184
233
 
185
234
  이후 `makdoong2-team validate` → `npm test` 로 회귀를 확인한다.
186
235
 
@@ -231,7 +280,7 @@ npm run release:major # 1.3.1 → 2.0.0 (breaking)
231
280
  |---|---|
232
281
  | [ARCHITECTURE.md](./ARCHITECTURE.md) | **어떻게 동작하는가** — 모듈, 툴 API, state 스키마, 훅, 런타임 방어, 실패 모드 |
233
282
  | [DESIGN.md](./DESIGN.md) | **왜 이렇게 만들었는가** — 하네스 4기둥 (Constrain / Inform / Verify / Correct) 과 트레이드오프 |
234
- | [AGENTS.md](./AGENTS.md) | **개발 규약** — git commit, npm 배포, sealed workflow, state.sh 하드룰 |
283
+ | [CLAUDE.md](./CLAUDE.md) | **개발 규약** — git commit, npm 배포, sealed workflow, state.sh 하드룰 |
235
284
 
236
285
  ## 라이선스
237
286
 
@@ -85,7 +85,7 @@ bash <SCRIPTS_DIR>/state.sh get {ISSUE_KEY} '.stages."1_planning".substages."jir
85
85
 
86
86
  이미 완료된 하위 작업(done 마커, research 완료 등)이 있으면 건너뛰고 미완 지점부터 재개한다.
87
87
 
88
- > **⚠️ state.json 스키마 규약 (반드시 준수):** state.sh 의 모든 jq path 는 hierarchical 표기 `.stages."<PHASE>".substages."<SUBSTAGE>".<field>` 를 사용한다. flat 표기 `.stages."<PHASE>.<SUBSTAGE>"` 는 phantom 키를 만들어 verifier·auto_advance 를 무력화한다. state.sh 훅이 flat 표기 write 를 물리 차단한다. (참조: AGENTS.md "워크플로우 상태 & 위임 규약")
88
+ > **⚠️ state.json 스키마 규약 (반드시 준수):** state.sh 의 모든 jq path 는 hierarchical 표기 `.stages."<PHASE>".substages."<SUBSTAGE>".<field>` 를 사용한다. flat 표기 `.stages."<PHASE>.<SUBSTAGE>"` 는 phantom 키를 만들어 verifier·auto_advance 를 무력화한다. state.sh 훅이 flat 표기 write 를 물리 차단한다. (참조: CLAUDE.md "워크플로우 상태 & 위임 규약")
89
89
 
90
90
  ### 0-exit. 타깃 substage 가 이미 완료된 경우 (필수 — 최우선 체크)
91
91
 
@@ -72,7 +72,7 @@ permission:
72
72
  ```
73
73
  3. `hang_history` 배열 길이 ≥ 3 이면 **적극 개입 신호**. 다음 substage 진입 전 사용자에게 반드시 다음을 보고하고 진행 승인을 받는다:
74
74
  ```
75
- ⚠️ LLM 서버 hang 반복 (<N>회). local/qwen3.6-27b 인퍼런스 서버 상태 확인 필요.
75
+ ⚠️ LLM 서버 hang 반복 (<N>회). github-copilot/gpt-5.6-luna 모델 응답 상태 확인 필요.
76
76
  계속 진행할지, get_fallback_model 로 fallback 모델 시도할지 결정 부탁드립니다.
77
77
  ```
78
78
  4. `dispatch_stage` 최종 응답에 `outcome_kind: "session_gone"` 이 포함된 경우 (MAX_ATTEMPTS 소진): 위 규약과 무관하게 즉시 사용자 보고 후 대기.
@@ -87,7 +87,7 @@ bash <SCRIPTS_DIR>/state.sh get <이슈키> '.stages."2_implementation".substage
87
87
 
88
88
  기대: 모든 항목(boolean)이 `true`인 JSON 객체. 누락·`false`·문법 오류 = **REJECTED**.
89
89
 
90
- > **⚠️ 스키마 규약:** state.sh 의 모든 jq path 는 `.stages."<PHASE>".substages."<SUBSTAGE>".<field>` 형태를 따른다. 참조: AGENTS.md "워크플로우 상태 & 위임 규약".
90
+ > **⚠️ 스키마 규약:** state.sh 의 모든 jq path 는 `.stages."<PHASE>".substages."<SUBSTAGE>".<field>` 형태를 따른다. 참조: CLAUDE.md "워크플로우 상태 & 위임 규약".
91
91
 
92
92
  ### 2. 단계 명세 재대조
93
93
 
@@ -61,37 +61,37 @@ const TIER_RANK = { low: 1, medium: 2, high: 3, max: 4 };
61
61
  export function tierRank(tier) {
62
62
  return TIER_RANK[tier];
63
63
  }
64
- // Default chains. All agents now use local/qwen3.6-27b as primary (medium tier).
64
+ // Default chains. All agents now use github-copilot/gpt-5.6-luna (variant xhigh) as primary (medium tier).
65
65
  // Fallback chain degrades to strictly lower tier. Override per-agent via
66
66
  // makdoong2-team.json `agents` block.
67
67
  export const POLICIES = {
68
68
  "makdoong2-team-leader": {
69
- primary: { id: "local/qwen3.6-27b", variant: "high", tier: "medium" },
69
+ primary: { id: "github-copilot/gpt-5.6-luna", variant: "xhigh", tier: "medium" },
70
70
  fallbacks: [{ id: "github-copilot/claude-haiku-4.5", tier: "low" }],
71
71
  },
72
72
  "makdoong2-analyzer": {
73
- primary: { id: "local/qwen3.6-27b", variant: "high", tier: "medium" },
73
+ primary: { id: "github-copilot/gpt-5.6-luna", variant: "xhigh", tier: "medium" },
74
74
  fallbacks: [{ id: "github-copilot/claude-haiku-4.5", tier: "low" }],
75
75
  },
76
76
  // Research fan-out worker — one session per source, spawned in parallel.
77
77
  "makdoong2-researcher": {
78
- primary: { id: "local/qwen3.6-27b", variant: "high", tier: "medium" },
78
+ primary: { id: "github-copilot/gpt-5.6-luna", variant: "xhigh", tier: "medium" },
79
79
  fallbacks: [{ id: "github-copilot/claude-haiku-4.5", tier: "low" }],
80
80
  },
81
81
  "makdoong2-planner": {
82
- primary: { id: "local/qwen3.6-27b", variant: "high", tier: "medium" },
82
+ primary: { id: "github-copilot/gpt-5.6-luna", variant: "xhigh", tier: "medium" },
83
83
  fallbacks: [{ id: "github-copilot/claude-haiku-4.5", tier: "low" }],
84
84
  },
85
85
  "makdoong2-engineer": {
86
- primary: { id: "local/qwen3.6-27b", variant: "high", tier: "medium" },
86
+ primary: { id: "github-copilot/gpt-5.6-luna", variant: "xhigh", tier: "medium" },
87
87
  fallbacks: [{ id: "github-copilot/claude-haiku-4.5", tier: "low" }],
88
88
  },
89
89
  "makdoong2-publisher": {
90
- primary: { id: "local/qwen3.6-27b", variant: "high", tier: "medium" },
90
+ primary: { id: "github-copilot/gpt-5.6-luna", variant: "xhigh", tier: "medium" },
91
91
  fallbacks: [{ id: "github-copilot/claude-haiku-4.5", tier: "low" }],
92
92
  },
93
93
  "makdoong2-verifier": {
94
- primary: { id: "local/qwen3.6-27b", tier: "medium" },
94
+ primary: { id: "github-copilot/gpt-5.6-luna", variant: "xhigh", tier: "medium" },
95
95
  fallbacks: [{ id: "github-copilot/claude-haiku-4.5", tier: "low" }],
96
96
  },
97
97
  };
@@ -980,7 +980,7 @@ export const Makdoong2TeamPlugin = async ({ $, client, directory, worktree }) =>
980
980
  `• 다른 substage 작업 필요 시: 결과·스펙을 team-leader에게 반환하면 team-leader가 dispatch_stage로 라우팅.\n` +
981
981
  `• 상태 공유: \`state.sh set\` 으로 state.json 마커에 기록. team-leader가 읽어서 다음 단계 결정.\n\n` +
982
982
  `**아키텍처 원칙:** 각 substage는 self-contained. Inter-substage 의존은 team-leader 오케스트레이션을 통해서만 흐르며, ` +
983
- `agent-to-agent 직접 호출은 금지된다. 참조: AGENTS.md "워크플로우 상태 & 위임 규약".`);
983
+ `agent-to-agent 직접 호출은 금지된다. 참조: CLAUDE.md "워크플로우 상태 & 위임 규약".`);
984
984
  }
985
985
  }
986
986
  else if (agent && SEALED_SUBAGENTS.has(agent) && DELEGATION_LIKE_NAME.test(toolLower) && !KNOWN_SAFE_TOOLS.has(toolLower)) {
@@ -1040,7 +1040,7 @@ export const Makdoong2TeamPlugin = async ({ $, client, directory, worktree }) =>
1040
1040
  `• Planning 단계 (planner): "무엇을 만들지" 결정만. 실제 파일 생성은 implementation 단계로 위임.\n` +
1041
1041
  `• Analysis 단계 (analyzer): workspace-analysis.json 1개만 생성 가능 (Write 툴 사용).\n` +
1042
1042
  `• 초안 파일 필요 시: spec을 team-leader에게 반환 → dev 단계에서 engineer가 구현.\n\n` +
1043
- `**참조**: agents/${agent}.md "금지" 섹션, AGENTS.md "워크플로우 상태 & 위임 규약"`);
1043
+ `**참조**: agents/${agent}.md "금지" 섹션, CLAUDE.md "워크플로우 상태 & 위임 규약"`);
1044
1044
  }
1045
1045
  const hookIssue = sessionIssue.get(sessionID ?? "") ?? "";
1046
1046
  const r = await runScript(HOOKS_DIR, "guard-bash.sh", cmd, hookIssue);
@@ -5,7 +5,7 @@
5
5
  // client. The plugin passes its real `client` at call sites; tests inject a
6
6
  // scripted mock via the same shape.
7
7
  //
8
- // Design invariants (see AGENTS.md and Oracle diagnosis for rationale):
8
+ // Design invariants (see CLAUDE.md and Oracle diagnosis for rationale):
9
9
  // INV-1: `!status` alone must never mean "idle". A missing status entry can
10
10
  // equally mean "session not registered yet" or "session cleaned up".
11
11
  // Idle is confirmed only by `status.type === "idle"` AFTER we have
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "makdoong2-team",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -63,7 +63,7 @@ echo "$matches" | while IFS=: read -r file line rest; do
63
63
  done
64
64
 
65
65
  cat >&2 <<EOF
66
- state.json 스키마 규약 (AGENTS.md "state.json 스키마 규약 (hardrule)" 참조):
66
+ state.json 스키마 규약 (CLAUDE.md "state.json 스키마 규약 (hardrule)" 참조):
67
67
  hierarchical : .stages."<PHASE>".substages."<SUBSTAGE>".<field>
68
68
  flat (금지) : .stages."<PHASE>.<SUBSTAGE>".<field>
69
69
 
@@ -60,32 +60,32 @@ export const TIER_RANK = { low: 1, medium: 2, high: 3, max: 4 };
60
60
  // agent-stage-config.ts (team-leader + planner/engineer/publisher/verifier).
61
61
  export const DEFAULT_POLICIES = Object.freeze({
62
62
  "makdoong2-team-leader": {
63
- primary: { id: "local/qwen3.6-27b", variant: "high", tier: "medium" },
63
+ primary: { id: "github-copilot/gpt-5.6-luna", variant: "xhigh", tier: "medium" },
64
64
  fallbacks: [{ id: "github-copilot/claude-haiku-4.5", tier: "low" }],
65
65
  },
66
66
  "makdoong2-analyzer": {
67
- primary: { id: "local/qwen3.6-27b", variant: "high", tier: "medium" },
67
+ primary: { id: "github-copilot/gpt-5.6-luna", variant: "xhigh", tier: "medium" },
68
68
  fallbacks: [{ id: "github-copilot/claude-haiku-4.5", tier: "low" }],
69
69
  },
70
70
  // Research fan-out worker — one session per source, spawned in parallel.
71
71
  "makdoong2-researcher": {
72
- primary: { id: "local/qwen3.6-27b", variant: "high", tier: "medium" },
72
+ primary: { id: "github-copilot/gpt-5.6-luna", variant: "xhigh", tier: "medium" },
73
73
  fallbacks: [{ id: "github-copilot/claude-haiku-4.5", tier: "low" }],
74
74
  },
75
75
  "makdoong2-planner": {
76
- primary: { id: "local/qwen3.6-27b", variant: "high", tier: "medium" },
76
+ primary: { id: "github-copilot/gpt-5.6-luna", variant: "xhigh", tier: "medium" },
77
77
  fallbacks: [{ id: "github-copilot/claude-haiku-4.5", tier: "low" }],
78
78
  },
79
79
  "makdoong2-engineer": {
80
- primary: { id: "local/qwen3.6-27b", variant: "medium", tier: "medium" },
80
+ primary: { id: "github-copilot/gpt-5.6-luna", variant: "xhigh", tier: "medium" },
81
81
  fallbacks: [{ id: "github-copilot/claude-haiku-4.5", tier: "low" }],
82
82
  },
83
83
  "makdoong2-publisher": {
84
- primary: { id: "local/qwen3.6-27b", variant: "high", tier: "medium" },
84
+ primary: { id: "github-copilot/gpt-5.6-luna", variant: "xhigh", tier: "medium" },
85
85
  fallbacks: [{ id: "github-copilot/claude-haiku-4.5", tier: "low" }],
86
86
  },
87
87
  "makdoong2-verifier": {
88
- primary: { id: "local/qwen3.6-27b", tier: "medium" },
88
+ primary: { id: "github-copilot/gpt-5.6-luna", variant: "xhigh", tier: "medium" },
89
89
  fallbacks: [{ id: "github-copilot/claude-haiku-4.5", tier: "low" }],
90
90
  },
91
91
  });
@@ -36,8 +36,8 @@ console.log("\n[smoke-test] model-fallback-policy chain logic\n");
36
36
 
37
37
  // ── Default chain semantics ──
38
38
 
39
- t("makdoong2-team-leader: qwen → haiku on first failure", () => {
40
- const r = nextModel({ agent: "makdoong2-team-leader", current: "local/qwen3.6-27b", reason: "rate_limit" });
39
+ t("makdoong2-team-leader: gpt-5.6-luna → haiku on first failure", () => {
40
+ const r = nextModel({ agent: "makdoong2-team-leader", current: "github-copilot/gpt-5.6-luna", reason: "rate_limit" });
41
41
  eq(r.exhausted, false, "should not be exhausted");
42
42
  eq(r.next.id, "github-copilot/claude-haiku-4.5", "next should be haiku-4.5");
43
43
  });
@@ -48,23 +48,23 @@ t("makdoong2-team-leader: haiku → exhausted after second failure", () => {
48
48
  eq(r.next, null, "next should be null");
49
49
  });
50
50
 
51
- t("makdoong2-planner: qwen → haiku", () => {
52
- const r = nextModel({ agent: "makdoong2-planner", current: "local/qwen3.6-27b", reason: "5xx" });
51
+ t("makdoong2-planner: gpt-5.6-luna → haiku", () => {
52
+ const r = nextModel({ agent: "makdoong2-planner", current: "github-copilot/gpt-5.6-luna", reason: "5xx" });
53
53
  eq(r.next.id, "github-copilot/claude-haiku-4.5", "planner fallback should be haiku");
54
54
  });
55
55
 
56
- t("makdoong2-engineer: qwen → haiku (lower-tier degrade)", () => {
57
- const r = nextModel({ agent: "makdoong2-engineer", current: "local/qwen3.6-27b", reason: "context_exceeded" });
56
+ t("makdoong2-engineer: gpt-5.6-luna → haiku (lower-tier degrade)", () => {
57
+ const r = nextModel({ agent: "makdoong2-engineer", current: "github-copilot/gpt-5.6-luna", reason: "context_exceeded" });
58
58
  eq(r.next.id, "github-copilot/claude-haiku-4.5", "engineer fallback should be haiku");
59
59
  });
60
60
 
61
- t("makdoong2-publisher: qwen → haiku", () => {
62
- const r = nextModel({ agent: "makdoong2-publisher", current: "local/qwen3.6-27b" });
61
+ t("makdoong2-publisher: gpt-5.6-luna → haiku", () => {
62
+ const r = nextModel({ agent: "makdoong2-publisher", current: "github-copilot/gpt-5.6-luna" });
63
63
  eq(r.next.id, "github-copilot/claude-haiku-4.5", "publisher fallback should be haiku");
64
64
  });
65
65
 
66
- t("makdoong2-verifier: qwen → haiku", () => {
67
- const r = nextModel({ agent: "makdoong2-verifier", current: "local/qwen3.6-27b" });
66
+ t("makdoong2-verifier: gpt-5.6-luna → haiku", () => {
67
+ const r = nextModel({ agent: "makdoong2-verifier", current: "github-copilot/gpt-5.6-luna" });
68
68
  eq(r.next.id, "github-copilot/claude-haiku-4.5", "verifier fallback should be haiku");
69
69
  });
70
70
 
@@ -75,7 +75,7 @@ t("unknown agent returns exhausted", () => {
75
75
 
76
76
  t("unknown current model starts from primary", () => {
77
77
  const r = nextModel({ agent: "makdoong2-team-leader", current: "anthropic/claude-fictional" });
78
- eq(r.next.id, "local/qwen3.6-27b", "unknown current should start at primary");
78
+ eq(r.next.id, "github-copilot/gpt-5.6-luna", "unknown current should start at primary");
79
79
  });
80
80
 
81
81
  t("all default primaries are in DEFAULT_ALLOWED_PRIMARIES", () => {