@walwal-harness/cli 6.0.2 → 6.0.3

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/CHANGELOG.md CHANGED
@@ -29,6 +29,41 @@ docmeta:
29
29
 
30
30
  # Changelog
31
31
 
32
+ ## 6.0.3 — Visibility + Spawn 검증 + 사용자 슬래시 노출 제거 (2026-05-07)
33
+
34
+ Owner 의 두 지적을 동시 해결:
35
+ 1. "Dispatcher 와 대화 중인데 CEO 가 자리에 없다 / 회의실에 모이지도 않는다" — visibility 의무 부재
36
+ 2. "회사인데 왜 자꾸 나에게 명령을 요구하는가" — 사용자 facing 슬래시 잔재
37
+
38
+ ### Added
39
+ - `gotchas/dispatcher.md` [G-005] [G-006] — 사용자 슬래시 명령 요구 금지 + Owner 대화 중 dashboard 가시화 의무
40
+ - `gotchas/conductor.md` (신규) — [G-001] inline fallback 금지 (M-001 의 Conductor 적용) / [G-002] spawn 핸드오프 시 회의실 활용 / [G-003] Visibility Checklist 4 시점 / [G-004] Owner 진행 동의 묻지 말 것
41
+ - `skills/conductor/SKILL.md` §0.5 "Visibility Checklist (Inviolable)" 신설 — 매 tick 의 4 시점 progress.json partial update 의무 + spawn 사전 검증 (SKILL 존재 검사 → 없으면 escalate, inline fallback 금지)
42
+ - 신규 명령 `walwal-harness verify` — 17 SKILL invariants + progress schema + config mode_selection + memory 시스템 entry + deprecated commands 검사. 한 줄로 통합 점검.
43
+ - `apps/harness-dashboard` 의 `ActivityIndicator` 컴포넌트 — `last_activity` age 표시. 30 초 이상 정적 → "stale — 회사가 멈춰 보입니다" 빨간 표시.
44
+
45
+ ### Changed
46
+ - `commands/harness-next.md` **삭제** — 사용자 슬래시 노출 제거. v6 자율 회사에서 Owner 가 입력할 일 없음. `scripts/harness-next.sh` 는 회사 내부 도구로 유지 (Conductor 자율 호출).
47
+ - 9 개 SKILL 본문의 "/harness-next 자동 진행" 안내 → "자동 핸드오프 (Conductor 자율 시동)" 로 일괄 치환.
48
+ - `bin/init.js` install 의 commands cleanup 로직이 자동으로 deprecated `harness-next.md` 를 사용자 환경에서 제거 (기존 동작이 모든 `harness-*` 를 갱신하므로).
49
+
50
+ ### Removed
51
+ - `commands/harness-next.md` — 사용자 facing 슬래시 (자율 위반)
52
+
53
+ ### Migration (one-liner)
54
+ ```bash
55
+ npm install @walwal-harness/cli@latest
56
+ npx walwal-harness migrate # 이전 버전 사용자
57
+ npx walwal-harness verify # 설치 무결성 점검
58
+ ```
59
+
60
+ `verify` 가 점검하는 것:
61
+ - 17 개 SKILL 의 frontmatter (name, description) + 파일 존재
62
+ - progress.json schema (version ≥ 4, mode_decision, dispatch)
63
+ - config.json mode_selection 존재
64
+ - memory.md 시스템 entry (M-NEXUS-P3)
65
+ - deprecated 사용자 슬래시 (`.claude/commands/harness-next.md`) 잔존 여부
66
+
32
67
  ## 6.0.2 — `migrate` 가 memory 시스템 entry 까지 자동 처리 (2026-05-07)
33
68
 
34
69
  v6.0.1 patch 적용을 위해 사용자가 memory.md 의 [M-NEXUS-P3] 를 수동 추가해야 했던 불편을 제거. `npx walwal-harness migrate` 한 줄로 모두 처리됩니다.
package/bin/init.js CHANGED
@@ -1152,6 +1152,121 @@ function runMigrate(opts = {}) {
1152
1152
  console.log('');
1153
1153
  }
1154
1154
 
1155
+ // ─────────────────────────────────────────
1156
+ // Verify — 14 SKILL invariants + spawn whitelist + progress schema
1157
+ // ─────────────────────────────────────────
1158
+ function runVerify() {
1159
+ const expectedSkills = [
1160
+ 'dispatcher', 'conductor', 'meeting-manager', 'planner',
1161
+ 'cto', 'cqo', 'service-ops',
1162
+ 'generator-backend', 'generator-frontend', 'generator-designer', 'generator-devops',
1163
+ 'evaluator-code-quality', 'evaluator-functional', 'evaluator-visual',
1164
+ 'evaluator-architecture', 'evaluator-security',
1165
+ 'brainstorming',
1166
+ ];
1167
+ const requiredFrontmatter = ['name', 'description'];
1168
+
1169
+ console.log('');
1170
+ log('=== Verify: skill invariants + spawn whitelist + progress schema ===');
1171
+ let pass = 0;
1172
+ let fail = 0;
1173
+ const issues = [];
1174
+
1175
+ // 1) skill files
1176
+ for (const s of expectedSkills) {
1177
+ const local = path.join(CLAUDE_SKILLS_DIR, `harness-${s}`, 'SKILL.md');
1178
+ const exists = fs.existsSync(local);
1179
+ if (!exists) {
1180
+ issues.push(` ✗ skills/harness-${s}/SKILL.md MISSING`);
1181
+ fail++;
1182
+ continue;
1183
+ }
1184
+ const body = fs.readFileSync(local, 'utf8');
1185
+ const fmMatch = body.match(/^---\n([\s\S]*?)\n---/);
1186
+ if (!fmMatch) {
1187
+ issues.push(` ✗ harness-${s}: frontmatter 누락`);
1188
+ fail++;
1189
+ continue;
1190
+ }
1191
+ const missing = requiredFrontmatter.filter((k) => !new RegExp(`^${k}:`, 'm').test(fmMatch[1]));
1192
+ if (missing.length) {
1193
+ issues.push(` ✗ harness-${s}: frontmatter [${missing.join(',')}] 누락`);
1194
+ fail++;
1195
+ continue;
1196
+ }
1197
+ pass++;
1198
+ }
1199
+ log(` skills: ${pass}/${expectedSkills.length} OK`);
1200
+
1201
+ // 2) progress.json schema (v6 = version 4 + mode_decision)
1202
+ const progressPath = path.join(HARNESS_DIR, 'progress.json');
1203
+ if (fs.existsSync(progressPath)) {
1204
+ try {
1205
+ const p = JSON.parse(fs.readFileSync(progressPath, 'utf8'));
1206
+ const schemaIssues = [];
1207
+ if ((p.version ?? 0) < 4) schemaIssues.push(`version=${p.version} (<4)`);
1208
+ if (!p.mode_decision) schemaIssues.push('mode_decision 누락');
1209
+ if (!p.dispatch) schemaIssues.push('dispatch 누락');
1210
+ if (schemaIssues.length) {
1211
+ issues.push(` ✗ progress.json schema: ${schemaIssues.join(', ')} → npx walwal-harness migrate`);
1212
+ fail++;
1213
+ } else {
1214
+ pass++;
1215
+ log(` progress.json: schema v${p.version} OK`);
1216
+ }
1217
+ } catch (e) {
1218
+ issues.push(` ✗ progress.json parse: ${e.message}`);
1219
+ fail++;
1220
+ }
1221
+ }
1222
+
1223
+ // 3) config.json mode_selection
1224
+ const configPath = path.join(HARNESS_DIR, 'config.json');
1225
+ if (fs.existsSync(configPath)) {
1226
+ try {
1227
+ const c = JSON.parse(fs.readFileSync(configPath, 'utf8'));
1228
+ if (!c.mode_selection) {
1229
+ issues.push(' ✗ config.json: mode_selection 누락 → npx walwal-harness migrate');
1230
+ fail++;
1231
+ } else {
1232
+ pass++;
1233
+ log(` config.json: mode_selection.owner=${c.mode_selection.owner} OK`);
1234
+ }
1235
+ } catch {}
1236
+ }
1237
+
1238
+ // 4) memory.md system entries
1239
+ const memoryPath = path.join(HARNESS_DIR, 'memory.md');
1240
+ if (fs.existsSync(memoryPath)) {
1241
+ const userMem = fs.readFileSync(memoryPath, 'utf8');
1242
+ const userIds = new Set(extractEntryIds(userMem));
1243
+ const required = ['M-NEXUS-P3'];
1244
+ const missing = required.filter((id) => !userIds.has(id));
1245
+ if (missing.length) {
1246
+ issues.push(` ✗ memory.md: 시스템 entry [${missing.join(',')}] 누락 → npx walwal-harness migrate`);
1247
+ fail++;
1248
+ } else {
1249
+ pass++;
1250
+ log(' memory.md: 시스템 entry OK');
1251
+ }
1252
+ }
1253
+
1254
+ // 5) deprecated user-facing slash commands
1255
+ const deprecated = path.join(PROJECT_ROOT, '.claude', 'commands', 'harness-next.md');
1256
+ if (fs.existsSync(deprecated)) {
1257
+ issues.push(' ⚠ .claude/commands/harness-next.md 존재 — v6.0.3 부터 회사 내부 도구로 전환됨. `npx walwal-harness --force` 또는 직접 삭제 권장');
1258
+ }
1259
+
1260
+ console.log('');
1261
+ if (fail === 0) {
1262
+ log(`✓ Verify PASS — ${pass} 개 invariant 통과.`);
1263
+ } else {
1264
+ log(`✖ Verify FAIL — ${fail} 개 issue 발견:`);
1265
+ for (const i of issues) console.log(i);
1266
+ }
1267
+ console.log('');
1268
+ }
1269
+
1155
1270
  function main() {
1156
1271
  if (isHelp) {
1157
1272
  showHelp();
@@ -1168,6 +1283,11 @@ function main() {
1168
1283
  return;
1169
1284
  }
1170
1285
 
1286
+ if (subcommand === 'verify') {
1287
+ runVerify();
1288
+ return;
1289
+ }
1290
+
1171
1291
  // Legacy subcommands — redirect to new equivalents
1172
1292
  if (subcommand === 'studio' || subcommand === 'studio-v4' || subcommand === 'v4') {
1173
1293
  log('NOTE: "studio" and "v4" subcommands are replaced by "team".');
@@ -0,0 +1,77 @@
1
+ ---
2
+ docmeta:
3
+ id: gotchas-conductor
4
+ title: Gotchas — Conductor (Autonomous Engine)
5
+ type: input
6
+ createdAt: 2026-05-07T00:00:00Z
7
+ updatedAt: 2026-05-07T00:00:00Z
8
+ source:
9
+ producer: agent
10
+ skillId: harness-dispatcher
11
+ inputs:
12
+ - documentId: user-feedback-v6.0.2
13
+ uri: (inline — Owner 의 "잘 워킹하고 있다는 느낌이 들지 않는다" 지적)
14
+ relation: output-from
15
+ sections:
16
+ - sourceRange: { startLine: 1, endLine: 1 }
17
+ targetRange: { startLine: 17, endLine: 60 }
18
+ tags: [gotchas, conductor, autonomy, visibility, ghost-spawn]
19
+ ---
20
+
21
+ # Gotchas — Conductor (자율 실행 엔진)
22
+
23
+ > Conductor 는 walwal-harness 의 손. Dispatcher (CEO) 가 GOAL 을 확정하면 손이 알아서 돌린다. 매 세션 시작 / 매 tick 시 이 파일을 읽고 같은 실수를 반복하지 않는다.
24
+
25
+ ### [G-001] 정의되지 않은 부서를 inline 으로 처리하지 말 것 (M-001 의 Conductor 적용)
26
+ - **Date**: 2026-05-07
27
+ - **Status**: verified
28
+ - **Trigger**: v6.0.2 install 환경에서 Conductor 가 `evaluator-uiux` (정의 X) 를 spawn 하려다 "별도 SKILL 이 없으므로 Conductor 가 직접 검증" 식으로 inline 처리. Owner 가 "잘 워킹하고 있다는 느낌이 들지 않는다" 보고.
29
+ - **Wrong**: spawn 대상이 `.claude/skills/harness-<name>/SKILL.md` 에 없을 때 (a) Conductor 가 inline 검증으로 우회 (b) 사용자 모르게 fallback 으로 진행.
30
+ - **Right**: spawn 직전 SKILL 존재 검사. 없으면 즉시 escalate:
31
+ ```bash
32
+ bash scripts/harness-progress-set.sh . \
33
+ '.failure = {"agent":"conductor","location":"spawn","message":"unknown agent: evaluator-uiux","retry_target":null} |
34
+ .next_agent = "dispatcher" |
35
+ .agent_status = "blocked"'
36
+ ```
37
+ Dispatcher 가 받아 Owner 에게 "정의되지 않은 부서 호출 시도. 표준 chain (code-quality/functional/visual) 또는 신규 SKILL 등록 필요" 보고.
38
+ - **Why**: M-001 ("선언만 된 유령 스킬") 의 Conductor 차원 적용. inline 우회는 (a) 사용자 신뢰 깨짐 (b) audit 흔적 부재 (c) verify 명령으로 catch 불가능.
39
+ - **Scope**: 모든 spawn 결정. Tick Loop §5 spawn 결정 트리.
40
+
41
+ ### [G-002] Spawn 핸드오프 시 회의실 활용 (visibility)
42
+ - **Date**: 2026-05-07
43
+ - **Status**: verified
44
+ - **Trigger**: Owner 발화 "CQO/COO/회의실 등에 모이지도 않고…"
45
+ - **Wrong**: spawn 핸드오프 시 progress.json 만 갱신하고 `meetings.active` 미사용. dashboard 에서 회의실이 텅 빔.
46
+ - **Right**: 핸드오프 직전 from→to 짧은 회의를 시각화:
47
+ ```bash
48
+ # 핸드오프 시작
49
+ bash scripts/harness-progress-set.sh . \
50
+ '.meetings.active = ["dispatcher","planner"] | .meetings.cadence = "handoff"'
51
+ sleep 1.5 # 시각적으로 회의실에 잠깐 모임
52
+ # 실제 spawn
53
+ bash scripts/harness-progress-set.sh . \
54
+ '.meetings.active = [] | .current_agent = "planner" | .agent_status = "running"'
55
+ ```
56
+ - **Why**: NEXUS 메타포 — 핸드오프 = 짧은 회의. dashboard 에서 회의실로 두 미니피규어 텔레포트 → 회사가 진짜 일한다는 신뢰.
57
+ - **Scope**: 모든 inter-agent 핸드오프.
58
+
59
+ ### [G-003] Visibility Checklist 4 시점 누락 금지 (Inviolable)
60
+ - **Date**: 2026-05-07
61
+ - **Status**: verified
62
+ - **Trigger**: G-002 의 일반화. Conductor 가 매 tick 마다 progress.json 의 4 시점 partial update 를 누락하면 dashboard 가 stale.
63
+ - **Wrong**: Conductor 가 spawn → 검증 → 결과 처리 사이에 progress.json 갱신을 잊거나 일부만 함.
64
+ - **Right**: 매 tick 의 4 시점에 의무 update (skills/conductor/SKILL.md §0.5 참조):
65
+ 1. **tick 시작**: `current_agent="conductor"`, `agent_status="running"`, `conductor.last_tick`, `tick_count++`
66
+ 2. **spawn 직전**: `meetings.active=[from,to]`, `meetings.cadence="handoff"` (1~2초)
67
+ 3. **spawn 직후**: `meetings.active=[]`, `current_agent="<spawned>"`, `agent_status="running"`
68
+ 4. **tick 완료**: `current_agent` 그대로 (다음 에이전트 작업 중) 또는 `null` + `agent_status="completed"`
69
+ - **Scope**: 모든 tick 사이클. 1~3 시점 누락 시 dashboard 의 회의실 텔레포트 / 미니피규어 활동 시각화 깨짐.
70
+
71
+ ### [G-004] Owner 에게 진행 동의 묻지 말 것 (Dispatcher [G-002] 의 Conductor 적용)
72
+ - **Date**: 2026-05-07
73
+ - **Status**: verified
74
+ - **Trigger**: NEXUS P3 위반 패턴 재발 방지
75
+ - **Wrong**: Conductor 가 Eval PASS 후 "다음 sprint 시작할까요?" 같은 질문을 Dispatcher 통해 전달.
76
+ - **Right**: PASS → 다음 평가자 chain / sprint advance 자동. FAIL → retry_target 자동 라우팅. 3 회 연속 FAIL / 인시던트 / GOAL 위반 시에만 escalation.
77
+ - **Scope**: Tick Loop §6 Escalation 트리거.
@@ -63,6 +63,31 @@ docmeta:
63
63
  - **Why**: 명료화 인터럽트가 자율성 위반의 우회 통로가 되지 않도록.
64
64
  - **Scope**: dispatcher 의 GOAL 정립 단계.
65
65
 
66
+ ### [G-005] 사용자에게 슬래시 명령을 입력하라고 요구하지 말 것
67
+ - **Date**: 2026-05-07
68
+ - **Status**: verified
69
+ - **Trigger**: Owner 발화 "회사인데 왜 자꾸 나에게 무언가 요청하는가? CEO 가 알아서 결정하면 될것을"
70
+ - **Wrong**: 응답에 "/harness-next 입력하세요", "/harness-evaluator-functional 호출하세요", "다음은 /harness-planner 슬래시 명령" 식으로 Owner 에게 회사 내부 진행 도구를 노출/요구.
71
+ - **Right**: 모든 슬래시 핸드오프 (`/harness-next`, `/harness-planner`, `/harness-evaluator-*` 등) 는 **회사 내부 자동화** 다. SKILL 의 On Complete 에서 직접 핸드오프하거나 `scripts/harness-next.sh` 를 호출. Owner 는 결과 보고와 escalation 만 본다.
72
+ - **Why**: NEXUS 메타포 — Owner 는 회사가 어떤 도구로 일하는지 신경쓰지 않는다. 슬래시 노출은 (a) 자율 실행 깨짐 (b) 정체성 (Owner ≠ CEO) 흐림.
73
+ - **Scope**: 모든 응답 문구. 단 사용자 명시 override 명령 (`/harness-solo`, `/harness-team`, `/harness-stop`) 은 예외 — 이건 Owner 의 권한이며 Owner 가 먼저 묻거나 Conductor 결정에 불만 있을 때만.
74
+
75
+ ### [G-006] Owner 와 대화하는 동안 dashboard 가시화 의무
76
+ - **Date**: 2026-05-07
77
+ - **Status**: verified
78
+ - **Trigger**: Owner 발화 "dispatcher 로 대화 중일때도 CEO 는 자리에 없었고… 잘 워킹하고 있다는 느낌이 들지 않는다"
79
+ - **Wrong**: Dispatcher 가 Owner 의 메시지를 받고 응답을 작성하는 동안 progress.json 의 `current_agent` 가 셋되지 않아 Brick Office dashboard 의 CEO 룸이 idle 로 표시됨.
80
+ - **Right**: Owner 메시지 수신 즉시 첫 행동:
81
+ ```bash
82
+ bash scripts/harness-progress-set.sh . '.current_agent = "dispatcher" | .agent_status = "running" | .updated_at = "<iso>"'
83
+ ```
84
+ 응답 송신 직전 마지막 행동:
85
+ ```bash
86
+ bash scripts/harness-progress-set.sh . '.agent_status = "completed" | .updated_at = "<iso>"'
87
+ ```
88
+ → CEO 미니피규어가 typing → idle 깜빡임. Owner 가 dashboard 에서 "회사가 일하고 있다" 신뢰 획득.
89
+ - **Scope**: 모든 inbound owner message 처리.
90
+
66
91
  ### [G-004] Owner ↔ Conductor / Planner / Generator / Evaluator 직접 라우팅 금지
67
92
  - **Date**: 2026-05-07
68
93
  - **Status**: verified
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@walwal-harness/cli",
3
- "version": "6.0.2",
3
+ "version": "6.0.3",
4
4
  "description": "Production harness for AI agent engineering — NEXUS-adapted company metaphor (Dispatcher/CEO + Conductor + Meeting-Manager + COO/Planner + CTO + CQO + Service-Ops). Solo/Team mode, Brainstormer, Planner, Generator(BE/FE/Designer/DevOps), Evaluator chain (Code-Quality → Functional → Visual + Architecture/Security). Supports React, Next.js, and Flutter FE stacks.",
5
5
  "bin": {
6
6
  "walwal-harness": "bin/init.js"
@@ -69,8 +69,8 @@ jq '.agent_status = "completed" | .completed_agents += ["planner"]' .harness/p
69
69
  - `completed_agents` 에 `"brainstormer"` 추가
70
70
  - `next_agent` → `"planner"`
71
71
  3. `.harness/progress.log` 에 요약 추가: `Brainstormer → Planner (spec: <경로>)`
72
- 4. 출력: `"✓ Brainstormer 완료. brainstorm-spec.md 검토 후 승인 신호를 주세요. 승인 시 /harness-next 자동 진행 (Planner)."`
73
- 5. **사용자 승인 게이트**: 사용자의 명시적 승인 ("이 디자인 승인한다", "ok", "다음", "Planner 가자" 등) 을 기다린 후, **`/harness-next` 슬래시 명령을 호출하여 Planner 로 자동 핸드오프**.
72
+ 4. 출력: `"✓ Brainstormer 완료. brainstorm-spec.md 검토 후 승인 신호를 주세요. 승인 시 자동 핸드오프 (Conductor 자율 시동) (Planner)."`
73
+ 5. **사용자 승인 게이트**: 사용자의 명시적 승인 ("이 디자인 승인한다", "ok", "다음", "Planner 가자" 등) 을 기다린 후, **내부 핸드오프 (scripts/harness-next.sh) 를 호출하여 Planner 로 자동 핸드오프**.
74
74
  6. 사용자가 피드백/수정 요청을 하면 brainstorm-spec.md 를 갱신하고 다시 승인 요청. 승인 없이는 `/harness-next` 호출 금지 (HARD-GATE 준수).
75
75
 
76
76
  ### On Fail / Abort
@@ -28,6 +28,51 @@ Conductor 는 다음 시점에 **자동 시동**한다. 사용자 펌프 없이.
28
28
 
29
29
  자세한 anti-pattern → `.harness/gotchas/dispatcher.md` 의 [G-002] 자율 실행 위반.
30
30
 
31
+ ## 0.5 Visibility Checklist (Inviolable, 매 tick 의무)
32
+
33
+ Brick Office dashboard 가 회사의 활동을 정확히 비추려면 매 tick 의 4 시점에 progress.json partial update 가 누락 없이 발생해야 한다. Owner 의 "잘 워킹하고 있다는 느낌" 은 이 4 시점 update 의 누적이다.
34
+
35
+ ### 4 시점 의무
36
+
37
+ ```bash
38
+ # ① tick 시작 시점 — Conductor 자신을 typing 으로 표시
39
+ bash scripts/harness-progress-set.sh . \
40
+ ".current_agent = \"conductor\" | .agent_status = \"running\" |
41
+ .conductor.last_tick = \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\" |
42
+ .conductor.tick_count = ((.conductor.tick_count // 0) + 1)"
43
+
44
+ # ② spawn 직전 — 회의실로 from/to 텔레포트 (~1.5s 시각화)
45
+ bash scripts/harness-progress-set.sh . \
46
+ ".meetings.active = [\"conductor\",\"<spawn-target>\"] | .meetings.cadence = \"handoff\""
47
+ sleep 1.5
48
+
49
+ # ③ spawn 직후 — 회의 종료, spawned agent 가 현장 작업
50
+ bash scripts/harness-progress-set.sh . \
51
+ ".meetings.active = [] | .current_agent = \"<spawn-target>\" | .agent_status = \"running\""
52
+
53
+ # ④ tick 완료 — spawned agent 가 자체 SKILL 의 Session Boundary 따름
54
+ # Conductor 는 다음 tick 에서 ① 부터 다시 시작
55
+ ```
56
+
57
+ ### Spawn 사전 검증 (G-001)
58
+
59
+ spawn 결정 트리 §5 직전에 SKILL 존재 검사를 수행한다:
60
+
61
+ ```bash
62
+ TARGET="<spawn-candidate>"
63
+ if [ ! -f ".claude/skills/harness-${TARGET}/SKILL.md" ]; then
64
+ bash scripts/harness-progress-set.sh . \
65
+ ".failure = {\"agent\":\"conductor\",\"location\":\"spawn\",\"message\":\"unknown agent: ${TARGET}\",\"retry_target\":null} |
66
+ .next_agent = \"dispatcher\" | .agent_status = \"blocked\""
67
+ # Dispatcher 가 받아 Owner 에게 escalation
68
+ exit 0
69
+ fi
70
+ ```
71
+
72
+ **금지** — inline fallback ("SKILL 이 없으므로 Conductor 가 직접 검증") 으로 우회. M-001 의 "유령 스킬" 패턴 재발.
73
+
74
+ 자세한 anti-pattern → `.harness/gotchas/conductor.md` [G-001] ~ [G-004].
75
+
31
76
  ## 1. 정체성
32
77
 
33
78
  - **위치**: Dispatcher(CEO) 직속, Planner와 평행
@@ -73,8 +73,8 @@ jq '.agent_status = "completed" | .completed_agents += ["planner"]' .harness/p
73
73
  ```
74
74
  아카이빙 후 `dispatch.id` 는 `null` 로 리셋되므로, 다음 dispatcher 실행 시 새 D-NNN 이 할당된다.
75
75
  2. `.harness/progress.log`에 요약 한 줄 추가
76
- 3. 출력: `"✓ Dispatcher 완료. /harness-next 자동 진행."`
77
- 4. **즉시 `/harness-next` 슬래시 명령을 호출하여 다음 에이전트로 자동 핸드오프** (Solo 모드. Team 모드는 Lead가 별도 오케스트레이션). Brainstorming/Planner 단계가 아니면 사용자 승인 게이트 없음.
76
+ 3. 출력: `"✓ Dispatcher 완료. 자동 핸드오프 (Conductor 자율 시동)."`
77
+ 4. **즉시 내부 핸드오프 (scripts/harness-next.sh) 를 호출하여 다음 에이전트로 자동 핸드오프** (Solo 모드. Team 모드는 Lead가 별도 오케스트레이션). Brainstorming/Planner 단계가 아니면 사용자 승인 게이트 없음.
78
78
 
79
79
  ## Auto-Routing (UserPromptSubmit Hook)
80
80
 
@@ -41,8 +41,8 @@ jq '.agent_status = "completed" | .completed_agents += ["planner"]' .harness/p
41
41
  - `failure` 필드 초기화
42
42
  2. `feature-list.json`의 통과 feature `passes`에 `"evaluator-code-quality"` 추가
43
43
  3. `.harness/progress.log`에 PASS 요약 추가
44
- 4. 출력: `"✓ Evaluator-Code-Quality PASS. /harness-next 자동 진행."`
45
- 5. **즉시 `/harness-next` 슬래시 명령을 호출하여 다음 에이전트로 자동 핸드오프** (Solo 모드. Team 모드는 Lead가 별도 오케스트레이션).
44
+ 4. 출력: `"✓ Evaluator-Code-Quality PASS. 자동 핸드오프 (Conductor 자율 시동)."`
45
+ 5. **즉시 내부 핸드오프 (scripts/harness-next.sh) 를 호출하여 다음 에이전트로 자동 핸드오프** (Solo 모드. Team 모드는 Lead가 별도 오케스트레이션).
46
46
 
47
47
  ### On Fail
48
48
  1. progress.json 업데이트:
@@ -55,8 +55,8 @@ jq '.agent_status = "completed" | .completed_agents += ["planner"]' .harness/p
55
55
  - `sprint.retry_count` 증가
56
56
  2. `sprint.retry_count >= 10`이면 `agent_status` → `"blocked"`, 사용자 개입 요청
57
57
  3. `.harness/progress.log`에 FAIL 요약 추가
58
- 4. 출력: `"✖ Evaluator-Code-Quality FAIL. /harness-next 자동 진행 (재작업 대상으로 라우팅)."`
59
- 5. **즉시 `/harness-next` 슬래시 명령을 호출하여 `failure.retry_target` 으로 자동 핸드오프** (Solo 모드).
58
+ 4. 출력: `"✖ Evaluator-Code-Quality FAIL. 자동 핸드오프 (Conductor 자율 시동) (재작업 대상으로 라우팅)."`
59
+ 5. **즉시 내부 핸드오프 (scripts/harness-next.sh) 를 호출하여 `failure.retry_target` 으로 자동 핸드오프** (Solo 모드).
60
60
 
61
61
  ## Critical Mindset
62
62
 
@@ -43,8 +43,8 @@ jq '.agent_status = "completed" | .completed_agents += ["planner"]' .harness/p
43
43
  - `failure` 필드 초기화
44
44
  3. `feature-list.json`의 통과 feature `passes`에 `"evaluator-functional"` 추가
45
45
  4. `.harness/progress.log`에 PASS 요약 추가
46
- 5. 출력: `"✓ Evaluator-Functional PASS. /harness-next 자동 진행."`
47
- 6. **즉시 `/harness-next` 슬래시 명령을 호출하여 다음 에이전트로 자동 핸드오프** (Solo 모드. Team 모드는 Lead가 별도 오케스트레이션).
46
+ 5. 출력: `"✓ Evaluator-Functional PASS. 자동 핸드오프 (Conductor 자율 시동)."`
47
+ 6. **즉시 내부 핸드오프 (scripts/harness-next.sh) 를 호출하여 다음 에이전트로 자동 핸드오프** (Solo 모드. Team 모드는 Lead가 별도 오케스트레이션).
48
48
 
49
49
  ### On Fail
50
50
  1. **Screenshot Cleanup** — PASS 와 동일하게 스크린샷 파일 삭제 (FAIL 시에도 정리 필수).
@@ -58,8 +58,8 @@ jq '.agent_status = "completed" | .completed_agents += ["planner"]' .harness/p
58
58
  - `sprint.retry_count` 증가
59
59
  3. `sprint.retry_count >= 10`이면 `agent_status` → `"blocked"`, 사용자 개입 요청
60
60
  4. `.harness/progress.log`에 FAIL 요약 추가
61
- 5. 출력: `"✖ Evaluator-Functional FAIL. /harness-next 자동 진행 (재작업 대상으로 라우팅)."`
62
- 6. **즉시 `/harness-next` 슬래시 명령을 호출하여 `failure.retry_target` 으로 자동 핸드오프** (Solo 모드).
61
+ 5. 출력: `"✖ Evaluator-Functional FAIL. 자동 핸드오프 (Conductor 자율 시동) (재작업 대상으로 라우팅)."`
62
+ 6. **즉시 내부 핸드오프 (scripts/harness-next.sh) 를 호출하여 `failure.retry_target` 으로 자동 핸드오프** (Solo 모드).
63
63
 
64
64
  ## Critical Mindset
65
65
 
@@ -43,8 +43,8 @@ jq '.agent_status = "completed" | .completed_agents += ["planner"]' .harness/p
43
43
  - `failure` 필드 초기화
44
44
  3. `feature-list.json`의 통과 feature `passes`에 `"evaluator-visual"` 추가
45
45
  4. `.harness/progress.log`에 PASS 요약 추가
46
- 5. 출력: `"✓ Evaluator-Visual PASS. /harness-next 자동 진행 (아카이브)."`
47
- 6. **즉시 `/harness-next` 슬래시 명령을 호출하여 아카이브 단계로 자동 핸드오프** (Solo 모드. Team 모드는 Lead가 별도 오케스트레이션).
46
+ 5. 출력: `"✓ Evaluator-Visual PASS. 자동 핸드오프 (Conductor 자율 시동) (아카이브)."`
47
+ 6. **즉시 내부 핸드오프 (scripts/harness-next.sh) 를 호출하여 아카이브 단계로 자동 핸드오프** (Solo 모드. Team 모드는 Lead가 별도 오케스트레이션).
48
48
 
49
49
  ### On Fail
50
50
  1. **Screenshot Cleanup** — PASS 와 동일하게 스크린샷 파일 삭제 (FAIL 시에도 정리 필수).
@@ -58,8 +58,8 @@ jq '.agent_status = "completed" | .completed_agents += ["planner"]' .harness/p
58
58
  - `sprint.retry_count` 증가
59
59
  3. `sprint.retry_count >= 10`이면 `agent_status` → `"blocked"`, 사용자 개입 요청
60
60
  4. `.harness/progress.log`에 FAIL 요약 추가
61
- 5. 출력: `"✖ Evaluator-Visual FAIL. /harness-next 자동 진행 (재작업 대상으로 라우팅)."`
62
- 6. **즉시 `/harness-next` 슬래시 명령을 호출하여 `failure.retry_target` 으로 자동 핸드오프** (Solo 모드).
61
+ 5. 출력: `"✖ Evaluator-Visual FAIL. 자동 핸드오프 (Conductor 자율 시동) (재작업 대상으로 라우팅)."`
62
+ 6. **즉시 내부 핸드오프 (scripts/harness-next.sh) 를 호출하여 `failure.retry_target` 으로 자동 핸드오프** (Solo 모드).
63
63
 
64
64
  ## FE Playwright Mandatory Rule (v5.4)
65
65
 
@@ -39,8 +39,8 @@ jq '.agent_status = "completed" | .completed_agents += ["planner"]' .harness/p
39
39
  - `failure` 필드 초기화 (retry 성공 시)
40
40
  2. `feature-list.json` 의 해당 feature `passes` 에 `"generator-backend"` 추가
41
41
  3. `.harness/progress.log` 에 요약 추가
42
- 4. 출력: `"✓ Generator-Backend 완료. /harness-next 자동 진행."`
43
- 5. **즉시 `/harness-next` 슬래시 명령을 호출하여 다음 에이전트로 자동 핸드오프** (Solo 모드. Team 모드는 Lead가 별도 오케스트레이션).
42
+ 4. 출력: `"✓ Generator-Backend 완료. 자동 핸드오프 (Conductor 자율 시동)."`
43
+ 5. **즉시 내부 핸드오프 (scripts/harness-next.sh) 를 호출하여 다음 에이전트로 자동 핸드오프** (Solo 모드. Team 모드는 Lead가 별도 오케스트레이션).
44
44
 
45
45
  ## Startup (Adaptive Loading)
46
46
 
@@ -39,8 +39,8 @@ jq '.agent_status = "completed" | .completed_agents += ["planner"]' .harness/p
39
39
  - `failure` 필드 초기화 (retry 성공 시)
40
40
  2. `feature-list.json` 의 해당 feature `passes` 에 `"generator-frontend"` 추가
41
41
  3. `.harness/progress.log` 에 요약 추가
42
- 4. 출력: `"✓ Generator-Frontend 완료. /harness-next 자동 진행."`
43
- 5. **즉시 `/harness-next` 슬래시 명령을 호출하여 다음 에이전트로 자동 핸드오프** (Solo 모드. Team 모드는 Lead가 별도 오케스트레이션).
42
+ 4. 출력: `"✓ Generator-Frontend 완료. 자동 핸드오프 (Conductor 자율 시동)."`
43
+ 5. **즉시 내부 핸드오프 (scripts/harness-next.sh) 를 호출하여 다음 에이전트로 자동 핸드오프** (Solo 모드. Team 모드는 Lead가 별도 오케스트레이션).
44
44
 
45
45
  ## Startup (Adaptive Loading)
46
46
 
@@ -36,8 +36,8 @@ jq '.agent_status = "completed" | .completed_agents += ["planner"]' .harness/p
36
36
  - `completed_agents`에 `"planner"` 추가
37
37
  - `next_agent` → 파이프라인에 따라 결정 (FULLSTACK/BE-ONLY: `"generator-backend"`, FE-ONLY: `"generator-frontend"`)
38
38
  2. `.harness/progress.log`에 요약 추가
39
- 3. 출력: `"✓ Planner 완료. plan.md / api-contract.json 검토 후 승인 신호를 주세요. 승인 시 /harness-next 자동 진행."`
40
- 4. **사용자 승인 게이트**: 사용자의 명시적 승인 ("승인", "ok", "다음", "진행", "go" 등) 을 기다린 후, **`/harness-next` 슬래시 명령을 호출하여 다음 에이전트로 자동 핸드오프**.
39
+ 3. 출력: `"✓ Planner 완료. plan.md / api-contract.json 검토 후 승인 신호를 주세요. 승인 시 자동 핸드오프 (Conductor 자율 시동)."`
40
+ 4. **사용자 승인 게이트**: 사용자의 명시적 승인 ("승인", "ok", "다음", "진행", "go" 등) 을 기다린 후, **내부 핸드오프 (scripts/harness-next.sh) 를 호출하여 다음 에이전트로 자동 핸드오프**.
41
41
  5. 사용자가 피드백/수정 요청을 하면 plan.md / feature-list.json / api-contract.json 을 갱신하고 다시 승인 요청. 승인 없이는 `/harness-next` 호출 금지.
42
42
 
43
43
  ## Startup
@@ -1,82 +0,0 @@
1
- ---
2
- docmeta:
3
- id: harness-next
4
- title: /harness-next — 다음 에이전트로 자동 진행
5
- type: input
6
- createdAt: 2026-04-27T00:00:00Z
7
- updatedAt: 2026-04-27T00:00:00Z
8
- source:
9
- producer: user
10
- skillId: harness
11
- inputs: []
12
- tags: [harness, solo-mode, orchestration, command]
13
- ---
14
-
15
- # /harness-next — 다음 에이전트로 자동 진행
16
-
17
- 현재 에이전트의 완료 상태(`progress.json`)를 읽고 파이프라인 시퀀스에 따라 **다음 에이전트로 자동 진행**합니다. Solo 모드에서 매 단계마다 사용자가 직접 bash 명령을 칠 필요 없이 자동 핸드오프합니다.
18
-
19
- ## 실행 절차
20
-
21
- ### Step 1: harness-next.sh 실행
22
-
23
- ```bash
24
- bash scripts/harness-next.sh .
25
- ```
26
-
27
- 스크립트가 수행하는 작업:
28
- - `progress.json` 읽기 → `current_agent`, `agent_status`, `next_agent` 확인
29
- - Pre-Eval Gate (lint/type/test) 실행 — Generator → Evaluator 전환 시
30
- - Artifact prerequisite 검증
31
- - `.harness/handoff.json` 생성 (다음 에이전트 컨텍스트)
32
- - 에스컬레이션 체크 (3회 실패 시 → Planner)
33
- - 마지막 에이전트면 자동 archive 실행
34
-
35
- ### Step 2: handoff.json 읽고 다음 에이전트 **즉시 호출** (필수)
36
-
37
- > **중요**: Step 1 완료 후 사용자에게 "다음 단계를 실행하시겠습니까?" 같은 추가 확인을 받지 마세요. 사용자가 이미 `/harness-next`를 호출한 시점에 다음 단계 실행에 동의한 것으로 간주합니다. 곧바로 Skill 도구로 `to` 필드의 스킬을 호출하세요.
38
-
39
- ```bash
40
- cat .harness/handoff.json | jq '{from, to, sprint, prompt, model, thinking_mode, failure_context}'
41
- ```
42
-
43
- `to` 필드 값에 따라 자동으로 해당 스킬을 호출합니다:
44
-
45
- | `to` 값 | 호출할 스킬 |
46
- |---------|------------|
47
- | `dispatcher` | `harness-dispatcher` |
48
- | `brainstorming` | `harness-brainstorming` |
49
- | `planner` | `harness-planner` |
50
- | `generator-backend` | `harness-generator-backend` |
51
- | `generator-frontend` | `harness-generator-frontend` |
52
- | `generator-frontend-flutter` | `harness-generator-frontend-flutter` |
53
- | `evaluator-code-quality` | `harness-evaluator-code-quality` |
54
- | `evaluator-functional` | `harness-evaluator-functional` |
55
- | `evaluator-functional-flutter` | `harness-evaluator-functional-flutter` |
56
- | `evaluator-visual` | `harness-evaluator-visual` |
57
- | `archive` | (자동 처리됨, 새 dispatch 대기) |
58
- | `null` (blocked) | 멈춤. 사용자에게 차단 사유 안내 |
59
-
60
- ### Step 3: 호출된 스킬이 handoff.json을 컨텍스트로 사용
61
-
62
- `handoff.json.prompt` 에 thinking mode, sprint, 실패 컨텍스트가 포함되어 있으므로 그대로 사용합니다.
63
-
64
- ## 사용 시점
65
-
66
- - **자동 호출** (스킬이 알아서):
67
- - Dispatcher, Generator-*, Evaluator-* 완료 직후 (사용자 검토 게이트 없음)
68
- - Planner / Brainstorming은 **사용자 승인 후** 스킬이 호출
69
- - **수동 호출** (사용자가 직접 입력):
70
- - 흐름이 멈춰서 다시 진행시키고 싶을 때
71
- - Eval FAIL 후 재시도를 시작할 때
72
- - `/harness-stop` 이후 재개
73
-
74
- ## Team 모드와의 관계
75
-
76
- Team 모드는 Lead worker가 자체 오케스트레이션 루프를 돌리므로 `/harness-next`가 필요 없습니다. 이 명령은 **Solo 모드 전용**입니다.
77
-
78
- ## 관련 명령
79
-
80
- - `/harness-solo` — Solo 모드 진입/전환
81
- - `/harness-team` — Team 모드 진입
82
- - `/harness-stop` — 진행 중단