@walwal-harness/cli 6.0.2 → 6.0.4

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,63 @@ docmeta:
29
29
 
30
30
  # Changelog
31
31
 
32
+ ## 6.0.4 — Sub-skill 협업 + Service-Ops 상시 + Team 병렬 spawn (2026-05-07)
33
+
34
+ ### Why
35
+ moon_web 사용자 보고 — v6.0.3 이후에도 (a) CTO-Frontend 가 흡수된 agency-agents sub-skill (UX/UI/A11y/Perf) 을 호출하지 않고 단독 작업, (b) build/test 중 Service-Ops 자리 비움 → stderr 의 컴파일/테스트 에러 무감시, (c) `mode=team` 인데도 Conductor 가 직렬로 1개씩 spawn 하여 Team 자동 결정 룰 (ready≥3, features≥6, depth≤2) 만족이 무의미해짐. 세 가지는 형식상 v6 였지만 실효는 6.0 이전 수준.
36
+
37
+ ### Changes
38
+ - **gotchas/generator-frontend.md [G-001]** — Sprint Workflow Step 2 에 5개 sub-skill 순차 호출 의무 (engineering-{react,flutter}-developer / design/ux-strategy / design/ui-component-spec / engineering-accessibility-reviewer / engineering-performance-engineer). 결과는 sprint-contract.md FE 섹션 `## Sub-skill Findings` 에 인용. 빈 블록 = Evaluator-Code-Quality FAIL.
39
+ - **gotchas/service-ops.md [G-001]** (신규) — build/test/deploy spawn 직전 동일 tick 에서 monitor stream-mode 동반 활성. 정규식 `(error|exception|TestFailure|Cannot find|Failed to compile)` 매칭 시 즉시 red-alert.
40
+ - **gotchas/conductor.md [G-005]** — Team mode 직렬 회귀 금지. 매 tick 시작 시 ready 목록 계산 → `min(ready, 3)` 동시 spawn + `team_state.team_<n>.assigned_feature/assigned_agent` 갱신 + `meetings.active=["t1-lead","t2-lead","t3-lead"]` standup 시각화.
41
+ - **gotchas/conductor.md [G-006]** — Service-Ops monitor 동반 spawn 룰을 Conductor SKILL §5 spawn 결정 트리에 명시.
42
+ - **skills/generator-frontend/SKILL.md** — Sprint Workflow §2.1 sub-skill 호출 시퀀스 표 + visibility partial update 패턴.
43
+ - **skills/conductor/SKILL.md** — §5 spawn 결정 트리에 두 라인 추가 + §5.1 Team mode 병렬 알고리즘 + §5.2 Service-Ops 동반 spawn 의사코드.
44
+
45
+ ### Migration
46
+ 기존 사용자:
47
+ ```bash
48
+ npm install @walwal-harness/cli@latest
49
+ npx walwal-harness migrate # gotchas/service-ops.md 자동 추가
50
+ npx walwal-harness verify
51
+ ```
52
+ sub-skill 호출은 generator-frontend SKILL.md 가 갱신되면 다음 sprint 부터 자동 적용. 진행 중 sprint 의 FE 섹션은 Eval-Code-Quality 가 빈 `## Sub-skill Findings` 를 잡아내며 retry 유도.
53
+
54
+ ## 6.0.3 — Visibility + Spawn 검증 + 사용자 슬래시 노출 제거 (2026-05-07)
55
+
56
+ Owner 의 두 지적을 동시 해결:
57
+ 1. "Dispatcher 와 대화 중인데 CEO 가 자리에 없다 / 회의실에 모이지도 않는다" — visibility 의무 부재
58
+ 2. "회사인데 왜 자꾸 나에게 명령을 요구하는가" — 사용자 facing 슬래시 잔재
59
+
60
+ ### Added
61
+ - `gotchas/dispatcher.md` [G-005] [G-006] — 사용자 슬래시 명령 요구 금지 + Owner 대화 중 dashboard 가시화 의무
62
+ - `gotchas/conductor.md` (신규) — [G-001] inline fallback 금지 (M-001 의 Conductor 적용) / [G-002] spawn 핸드오프 시 회의실 활용 / [G-003] Visibility Checklist 4 시점 / [G-004] Owner 진행 동의 묻지 말 것
63
+ - `skills/conductor/SKILL.md` §0.5 "Visibility Checklist (Inviolable)" 신설 — 매 tick 의 4 시점 progress.json partial update 의무 + spawn 사전 검증 (SKILL 존재 검사 → 없으면 escalate, inline fallback 금지)
64
+ - 신규 명령 `walwal-harness verify` — 17 SKILL invariants + progress schema + config mode_selection + memory 시스템 entry + deprecated commands 검사. 한 줄로 통합 점검.
65
+ - `apps/harness-dashboard` 의 `ActivityIndicator` 컴포넌트 — `last_activity` age 표시. 30 초 이상 정적 → "stale — 회사가 멈춰 보입니다" 빨간 표시.
66
+
67
+ ### Changed
68
+ - `commands/harness-next.md` **삭제** — 사용자 슬래시 노출 제거. v6 자율 회사에서 Owner 가 입력할 일 없음. `scripts/harness-next.sh` 는 회사 내부 도구로 유지 (Conductor 자율 호출).
69
+ - 9 개 SKILL 본문의 "/harness-next 자동 진행" 안내 → "자동 핸드오프 (Conductor 자율 시동)" 로 일괄 치환.
70
+ - `bin/init.js` install 의 commands cleanup 로직이 자동으로 deprecated `harness-next.md` 를 사용자 환경에서 제거 (기존 동작이 모든 `harness-*` 를 갱신하므로).
71
+
72
+ ### Removed
73
+ - `commands/harness-next.md` — 사용자 facing 슬래시 (자율 위반)
74
+
75
+ ### Migration (one-liner)
76
+ ```bash
77
+ npm install @walwal-harness/cli@latest
78
+ npx walwal-harness migrate # 이전 버전 사용자
79
+ npx walwal-harness verify # 설치 무결성 점검
80
+ ```
81
+
82
+ `verify` 가 점검하는 것:
83
+ - 17 개 SKILL 의 frontmatter (name, description) + 파일 존재
84
+ - progress.json schema (version ≥ 4, mode_decision, dispatch)
85
+ - config.json mode_selection 존재
86
+ - memory.md 시스템 entry (M-NEXUS-P3)
87
+ - deprecated 사용자 슬래시 (`.claude/commands/harness-next.md`) 잔존 여부
88
+
32
89
  ## 6.0.2 — `migrate` 가 memory 시스템 entry 까지 자동 처리 (2026-05-07)
33
90
 
34
91
  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,92 @@
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-005] Team mode 직렬 회귀 금지 — ready ≥ 2 면 병렬 spawn (status: verified)
72
+ - **Date**: 2026-05-07
73
+ - **Trigger**: Owner 보고 "솔로모드로 만 동작하는것처럼 다중 에이전트 상태가 아님" (moon_web 2026-05-07). progress.json.mode="team" 인데도 Conductor 가 한 번에 한 generator 만 spawn 하고 evaluator 핸드오프도 직렬.
74
+ - **Wrong**: Tick 마다 ready 목록에서 1개만 골라 spawn. tmux 의 T1/T2/T3 패널이 비어있어도 무시.
75
+ - **Right**: 매 tick 시작 시 ready 목록 (depends_on 충족 + agent_status≠running) 을 계산. mode="team" 이면 **min(ready, 3)** 만큼 동시 spawn — 각 팀 슬롯 (T1/T2/T3) 에 배정 + progress.json.team_state.team_<n>.assigned_feature, .assigned_agent 갱신. 동시 spawn 직전 meetings.active=["t1-lead","t2-lead","t3-lead"] 로 짧은 standup 시각화.
76
+ - **Scope**: §4 Tick Loop, §5 Spawn 결정 트리. Solo 모드는 1개 spawn 유지.
77
+ - **Why**: Team 자동 결정 룰 (ready≥3, features≥6, depth≤2) 을 만족시켜놓고 직렬로 돌리면 Team mode 가 형식상 활성이지만 실효 없음. 비용 + 시각적 신뢰 모두 낭비.
78
+
79
+ ### [G-006] Build/Deploy 실행 중 service-ops/monitor 동반 spawn (status: verified)
80
+ - **Date**: 2026-05-07
81
+ - **Trigger**: Owner 보고 "Service ops 는 build/배포 환경 로그 모니터링하면서 에러 캐치해야 하는데 공석". moon_web 빌드 중 `flutter test --platform chrome` 의 WebSocketChannelException 이 stderr 에 흘렀지만 service-ops 룸은 빈 채.
82
+ - **Wrong**: generator-frontend / evaluator-functional 이 build·test 명령을 단독 실행. cron 사이 공백 동안 stderr 무감시.
83
+ - **Right**: build/test/deploy 를 트리거하는 spawn 직전, 동일 tick 에 service-ops/monitor 를 stream-mode 로 함께 spawn (handoff-bridge). 자식 프로세스 종료 시까지 stream_active=true. 스트림 매칭 정규식 (error|exception|TestFailure|Cannot find|Failed to compile) 시 즉시 red-alert.
84
+ - **Scope**: §5 Spawn 결정 트리에 "[generator-* or evaluator-functional spawn 직전] → service-ops/monitor stream-mode 동시 spawn" 라인 추가.
85
+
86
+ ### [G-004] Owner 에게 진행 동의 묻지 말 것 (Dispatcher [G-002] 의 Conductor 적용)
87
+ - **Date**: 2026-05-07
88
+ - **Status**: verified
89
+ - **Trigger**: NEXUS P3 위반 패턴 재발 방지
90
+ - **Wrong**: Conductor 가 Eval PASS 후 "다음 sprint 시작할까요?" 같은 질문을 Dispatcher 통해 전달.
91
+ - **Right**: PASS → 다음 평가자 chain / sprint advance 자동. FAIL → retry_target 자동 라우팅. 3 회 연속 FAIL / 인시던트 / GOAL 위반 시에만 escalation.
92
+ - **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
@@ -1,5 +1,31 @@
1
+ ---
2
+ docmeta:
3
+ id: generator-frontend
4
+ title: Gotchas — Generator-Frontend
5
+ type: intermediate
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
+ tags: [gotcha, generator-frontend, sub-skill, agency-agents]
13
+ ---
14
+
1
15
  # Gotchas — Generator-Frontend
2
16
 
3
17
  > Dispatcher가 관리. Generator-Frontend는 세션 시작 시 이 파일을 읽고 같은 실수를 반복하지 않습니다.
4
18
 
5
- <!-- 항목이 추가되면 아래에 기록됩니다 -->
19
+ ## [G-001] CTO-Frontend 단독 작업 금지 — 흡수된 agency-agents sub-skill 명시 호출 (status: verified)
20
+
21
+ - **Why**: walwal-harness v6 는 agency-agents (MIT) 의 design/UX/A11y/perf 패턴을 부서별로 흡수했지만, generator-frontend SKILL 에는 sub-skill 호출 의무가 누락되어 CTO-Frontend 가 단독으로 컴포넌트를 찍어내고 끝나는 회귀가 있었다 (moon_web 2026-05-07).
22
+ - **How to apply**:
23
+ - **Sprint Workflow Step 2 (구현)** 진입 시, 다음 sub-skill 결과를 **순차 호출 후 본 구현에 반영**한다 — 결과 미반영은 PASS 금지:
24
+ 1. **engineering-react-developer** (또는 -flutter-developer) — 컴포넌트 골격 패턴 결정
25
+ 2. **design/ux-strategy** (CTO-Designer 흡수) — 사용자 흐름 / 정보 구조 검증
26
+ 3. **design/ui-component-spec** — 토큰 / variant / state 매핑
27
+ 4. **engineering-accessibility-reviewer** — WCAG AA + 키보드 네비
28
+ 5. **engineering-performance-engineer** — RSC 우선 / hydration 비용 / IntersectionObserver
29
+ - 호출 결과는 sprint-contract.md FE 섹션의 `## Sub-skill Findings` 블록에 요약 반영. 빈 블록 = FAIL.
30
+ - tmux/3D 대시보드에 visibility 보장: 각 sub-skill 호출 직전 `progress.json.meetings.active = ["generator-frontend", "<sub-skill>"]` partial update 후 1.5s, 호출 후 `[]` 로 복귀.
31
+ - **References**: skills/cto/SKILL.md "agency-agents (MIT) 흡수" 섹션, skills/generator-designer/SKILL.md.
@@ -0,0 +1,27 @@
1
+ ---
2
+ docmeta:
3
+ id: service-ops
4
+ title: Gotchas — Service-Ops
5
+ type: intermediate
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
+ tags: [gotcha, service-ops, monitor, presence]
13
+ ---
14
+
15
+ # Gotchas — Service-Ops
16
+
17
+ > Dispatcher가 관리. Service-Ops 는 세션 시작 시 이 파일을 읽고 같은 실수를 반복하지 않습니다.
18
+
19
+ ## [G-001] Build/Deploy 진행 중 자리 비움 금지 — monitor 모듈 활성 의무 (status: verified)
20
+
21
+ - **Why**: Service-Ops 의 monitor 는 cron + red-alert 이벤트로만 spawn 되도록 설계됐으나, generator/evaluator 가 build·flutter test·deploy 를 실행하는 동안에는 cron 주기 사이 공백이 길어 대시보드에서 "SERVICE-OPS 룸 빈 채" 가 관찰됨 (moon_web 2026-05-07). 빌드 stderr 의 WebSocketChannelException, 컴파일 에러, dart analyze warning 을 실시간으로 캐치하지 못하면 이후 evaluator-functional 단계에서야 발견 → 비용 증가.
22
+ - **How to apply**:
23
+ - Conductor 가 generator-* 또는 evaluator-functional 을 spawn 하기 **직전**, 동일 tick 에 service-ops/monitor 를 **stream-mode 로 함께 spawn** (handoff-bridge). progress.json.service_ops.monitor.stream_active = true.
24
+ - Stream-mode monitor 의 책임: 자식 프로세스 stdout/stderr 를 tail → 정규식 (`error:|exception|TestFailure|Cannot find|Failed to compile`) 매칭 시 즉시 conductor 에 red-alert 발행.
25
+ - 자식 프로세스 종료 시 stream_active = false + ops-report 짧은 요약 append.
26
+ - Visibility: monitor 활성 동안 progress.json.agents 에 service-ops minifig 가 service-ops 룸 (또는 모니터링 대상 룸 인접) 에 위치하도록 partial update.
27
+ - **References**: skills/service-ops/SKILL.md service_ops.monitor 섹션.
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.4",
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와 평행
@@ -97,8 +142,36 @@ idle ─► running ─► (waiting_meeting | waiting_owner | running) ─► co
97
142
  [all features PASS] → Phase Gate Meeting
98
143
  [Service-Ops cron due] → spawn service-ops monitor
99
144
  [ops-report ready] → handoff to CTO (spawn cto-review)
145
+ [generator-* / eval-functional spawn 직전] → 동시 spawn service-ops/monitor (stream-mode, G-006)
146
+ [mode=team & ready ≥ 2] → 동시 spawn min(ready,3) generator/evaluator (G-005)
147
+ ```
148
+
149
+ ### 5.1 Team mode 병렬 spawn (G-005)
150
+
151
+ `progress.json.mode == "team"` 이면 매 tick 시작 시 ready 목록을 계산하여 **동시 다발 spawn**:
152
+
153
+ ```bash
154
+ # ready = depends_on 충족 + agent_status != "running" 인 feature 의 다음 에이전트 목록
155
+ ready_count=$(jq '[.features[] | select(.depends_on // [] | all(. as $d | (.[$d].passes // []) | length > 0))] | length' .harness/feature-list.json)
156
+ slots=$(( ready_count < 3 ? ready_count : 3 ))
157
+ # slots 만큼 team_state.team_<n>.assigned_feature/assigned_agent 갱신 후 동시 Agent 호출
100
158
  ```
101
159
 
160
+ 직렬 회귀 (1 spawn → 완료 대기 → 다음 spawn) 는 Solo 모드에서만 허용. Team 모드에서 1개씩 처리하면 GOTCHA G-005 위반.
161
+
162
+ ### 5.2 Service-Ops monitor 동반 spawn (G-006)
163
+
164
+ generator-{backend,frontend,frontend-flutter,devops} 또는 evaluator-functional* 을 spawn 하기 직전, **동일 tick 에서** service-ops/monitor 를 stream-mode 로 함께 spawn:
165
+
166
+ ```bash
167
+ bash scripts/harness-progress-set.sh . \
168
+ '.service_ops.monitor.stream_active = true |
169
+ .service_ops.monitor.stream_target = "generator-frontend" |
170
+ .agents += [{"id":"service-ops","room":"service-ops","minifigState":"watching"}]'
171
+ ```
172
+
173
+ 자식 프로세스 종료 시 stream_active=false + ops-report append. 빌드 stderr 의 (error|exception|TestFailure|Cannot find|Failed to compile) 매칭 → 즉시 red-alert.
174
+
102
175
  ## 6. Escalation 트리거 & 양식
103
176
 
104
177
  | 트리거 | 양식 | Owner 응답 옵션 |
@@ -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
 
@@ -86,9 +86,29 @@ Team Mode 에서 Team Worker 가 호출할 때, 프롬프트에 `FEATURE_ID` 가
86
86
  ## Sprint Workflow
87
87
 
88
88
  1. **Sprint Contract FE 섹션 추가** — 컴포넌트 / API 연동 / 성공 기준
89
- 2. **구현** — 아래 "스택 치환 규칙" 엄수
90
- 3. **Self-Verification** — `ref.validation.pre_eval_gate` 에 나열된 명령 전부 실행
91
- 4. **Handoff** → Evaluator-Functional
89
+ 2. **Sub-skill 협업 (Inviolable, gotcha G-001)** — 본 구현 전, 흡수된 agency-agents (MIT) sub-skill 결과를 순차 반영. 누락 시 Eval FAIL.
90
+ 3. **구현** — 아래 "스택 치환 규칙" 엄수, sub-skill findings 를 sprint-contract.md FE 섹션 `## Sub-skill Findings` 블록에 인용
91
+ 4. **Self-Verification** — `ref.validation.pre_eval_gate` 에 나열된 명령 전부 실행
92
+ 5. **Handoff** → Evaluator-Functional
93
+
94
+ ### 2.1 Sub-skill 호출 시퀀스 (필수)
95
+
96
+ 각 sub-skill 호출 직전 visibility partial update:
97
+ ```bash
98
+ bash scripts/harness-progress-set.sh . \
99
+ '.meetings.active = ["generator-frontend","<sub-skill>"] | .meetings.cadence = "sub-skill"'
100
+ ```
101
+ 호출 후 `meetings.active = []` 복귀.
102
+
103
+ | # | Sub-skill (agency-agents 흡수처) | 산출물 (FE 섹션 인용) |
104
+ |---|----------------------------------|------------------------|
105
+ | 1 | `engineering-{react,flutter}-developer` (CTO 흡수) | 컴포넌트 골격 + state 관리 결정 |
106
+ | 2 | `design/ux-strategy` (Generator-Designer 흡수) | 사용자 흐름 / 정보 구조 검증 |
107
+ | 3 | `design/ui-component-spec` (Generator-Designer 흡수) | 토큰 / variant / state 매핑 |
108
+ | 4 | `engineering-accessibility-reviewer` (CTO 흡수) | WCAG AA + 키보드 네비 체크 |
109
+ | 5 | `engineering-performance-engineer` (CTO 흡수) | RSC / hydration / observer 결정 |
110
+
111
+ 빈 `## Sub-skill Findings` = Eval FAIL 으로 처리됨 (Evaluator-Code-Quality 게이트).
92
112
 
93
113
  ## 스택 치환 규칙 (Adaptive Core)
94
114
 
@@ -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` — 진행 중단