@walwal-harness/cli 6.0.0 → 6.0.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/CHANGELOG.md +56 -0
- package/assets/templates/memory.md +30 -2
- package/bin/init.js +73 -3
- package/gotchas/dispatcher.md +72 -0
- package/package.json +1 -1
- package/skills/conductor/SKILL.md +13 -0
- package/skills/dispatcher/SKILL.md +18 -0
package/CHANGELOG.md
CHANGED
|
@@ -29,6 +29,62 @@ docmeta:
|
|
|
29
29
|
|
|
30
30
|
# Changelog
|
|
31
31
|
|
|
32
|
+
## 6.0.2 — `migrate` 가 memory 시스템 entry 까지 자동 처리 (2026-05-07)
|
|
33
|
+
|
|
34
|
+
v6.0.1 patch 적용을 위해 사용자가 memory.md 의 [M-NEXUS-P3] 를 수동 추가해야 했던 불편을 제거. `npx walwal-harness migrate` 한 줄로 모두 처리됩니다.
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
- `bin/init.js` 의 `detectMigrationNeeded()` 가 memory.md 의 시스템 entry (M-NEXUS-*, M-SYS-*) 누락도 감지.
|
|
38
|
+
- `runMigrate()` 가 누락된 시스템 entry 를 template 에서 발췌해 사용자 memory.md 끝에 append. **사용자 [M-NNN] entry 는 무손상**.
|
|
39
|
+
- postinstall 안내 banner 가 누락된 memory entry 목록도 함께 표시.
|
|
40
|
+
|
|
41
|
+
### Migration (one-liner)
|
|
42
|
+
```bash
|
|
43
|
+
npm install @walwal-harness/cli@latest
|
|
44
|
+
npx walwal-harness migrate # progress + config + memory 한 번에
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`migrate` 가 처리하는 것:
|
|
48
|
+
- progress.json v3 → v4 (mode → "auto" + mode_decision)
|
|
49
|
+
- config.json mode_selection 자동 주입
|
|
50
|
+
- **(신규)** memory.md 시스템 entry append (M-NEXUS-P3 등)
|
|
51
|
+
- 변경 전 .harness/archive/migration-<ts>/ 에 progress / config / memory 자동 백업.
|
|
52
|
+
|
|
53
|
+
## 6.0.1 — Owner ↔ CEO 정체성 + 자율 실행 룰 강화 (2026-05-07)
|
|
54
|
+
|
|
55
|
+
v6.0.0 publish 직후 Owner 의 명시적 교정으로 발견된 두 가지 inviolable 룰 위반 패턴을 패키지에 정식 등재한 patch.
|
|
56
|
+
|
|
57
|
+
### 발견된 위반 패턴
|
|
58
|
+
- Dispatcher 응답이 사용자를 "CEO 직접 리뷰…" 로 호명 — 정체성 혼선
|
|
59
|
+
- "/harness-next 자동 진행하시겠습니까?" 식의 사용자 펌프 — NEXUS P3 자율 실행 위반
|
|
60
|
+
|
|
61
|
+
### Added
|
|
62
|
+
- `gotchas/dispatcher.md` — 신규 4개 entry ([G-001]~[G-004]) 정식 등재. install 시 사용자 `.harness/gotchas/dispatcher.md` 로 자동 복사.
|
|
63
|
+
- [G-001] 사용자를 CEO 로 다루지 말 것 (Owner ↔ CEO 정체성)
|
|
64
|
+
- [G-002] 사용자에게 진행 여부 묻지 말 것 (NEXUS P3 자율 실행)
|
|
65
|
+
- [G-003] GOAL 모호성 명료화는 짧게 한 번만
|
|
66
|
+
- [G-004] Owner ↔ Conductor/Planner/Generator/Evaluator 직접 라우팅 금지
|
|
67
|
+
- `assets/templates/memory.md` — 신규 [M-NEXUS-P3] 항목. 모든 신규 install 의 시작 memory 에 포함.
|
|
68
|
+
|
|
69
|
+
### Changed
|
|
70
|
+
- `skills/dispatcher/SKILL.md` 상단에 두 inviolable 섹션 신설:
|
|
71
|
+
- "정체성 — Owner ↔ CEO (NEXUS, Inviolable)"
|
|
72
|
+
- "자율 실행 원칙 (NEXUS P3, Inviolable)"
|
|
73
|
+
- `skills/conductor/SKILL.md` §0 "자율 시동 트리거" 신설 — Dispatcher GOAL 확정 / Planner feature-list 확정 / Eval PASS / Eval FAIL 4 시점에 자동 시동 명시.
|
|
74
|
+
|
|
75
|
+
### Why a patch (not a feature)
|
|
76
|
+
이 룰들은 v6.0.0 의 NEXUS 도큐트린에 이미 존재했지만 SKILL 본문에서 충분히 강제되지 않아 대화에서 위반이 발생. 룰 자체는 변경 없음, **명시화/강제력 강화** 만.
|
|
77
|
+
|
|
78
|
+
### Migration
|
|
79
|
+
이전 사용자 (v6.0.0 install 자) 가 patch 적용:
|
|
80
|
+
```bash
|
|
81
|
+
npm install @walwal-harness/cli@latest # 6.0.1 설치
|
|
82
|
+
# .claude/skills/ 와 .harness/gotchas/dispatcher.md 가 자동 갱신됨.
|
|
83
|
+
# .harness/memory.md 는 [G-NNN] entry 가 있으면 보존되므로
|
|
84
|
+
# [M-NEXUS-P3] 항목을 수동으로 메모에 추가하거나
|
|
85
|
+
# memory.md 백업 후 walwal-harness --force 로 template 재적용.
|
|
86
|
+
```
|
|
87
|
+
|
|
32
88
|
## 6.0.0 — NEXUS-Adapted Company Metaphor (2026-05-07)
|
|
33
89
|
|
|
34
90
|
회사 메타포로의 전면 전환. 기존 단일 dispatcher/planner/generator/evaluator 라인업을 NEXUS 도큐트린에 따라 7부서 + 14 에이전트 조직도로 재해석했습니다.
|
|
@@ -4,11 +4,25 @@ docmeta:
|
|
|
4
4
|
title: Harness Memory — 공유 학습 기록
|
|
5
5
|
type: input
|
|
6
6
|
createdAt: 2026-04-20T00:00:00Z
|
|
7
|
-
updatedAt: 2026-
|
|
7
|
+
updatedAt: 2026-05-07T00:00:00Z
|
|
8
8
|
source:
|
|
9
9
|
producer: user
|
|
10
10
|
skillId: harness
|
|
11
|
-
inputs:
|
|
11
|
+
inputs:
|
|
12
|
+
- documentId: doctrine-nexus
|
|
13
|
+
uri: ../../doctrine/nexus.md
|
|
14
|
+
relation: output-from
|
|
15
|
+
note: NEXUS Foundational Principle P3 (Continuous Loop > End-of-Pipeline) 의 권위 출처. M-NEXUS-P3 항목이 이를 운영 룰로 변환.
|
|
16
|
+
sections:
|
|
17
|
+
- sourceRange: { startLine: 32, endLine: 60 }
|
|
18
|
+
targetRange: { startLine: 56, endLine: 70 }
|
|
19
|
+
- documentId: gotchas-dispatcher
|
|
20
|
+
uri: ../../gotchas/dispatcher.md
|
|
21
|
+
relation: output-from
|
|
22
|
+
note: dispatcher [G-001]~[G-004] 가 본 memory 의 [M-NEXUS-P3] 적용 사례. inline 사용자 피드백 기반.
|
|
23
|
+
sections:
|
|
24
|
+
- sourceRange: { startLine: 17, endLine: 52 }
|
|
25
|
+
targetRange: { startLine: 56, endLine: 70 }
|
|
12
26
|
tags: [harness, memory, template]
|
|
13
27
|
---
|
|
14
28
|
|
|
@@ -53,6 +67,20 @@ docmeta:
|
|
|
53
67
|
- **Context**: 사용자가 대시보드 로그만 보고 진행 상황을 파악해야 하는데, 기존 축약 로그로는 4대 질문에 답이 안 보인다는 피드백.
|
|
54
68
|
- **Applies to**: Team Worker(Generator + Evaluator), Solo Mode Generator/Evaluator, 모든 `logev` 호출 지점.
|
|
55
69
|
|
|
70
|
+
### [M-NEXUS-P3] Owner ↔ CEO 단일 창구 + 자율 실행 (Inviolable)
|
|
71
|
+
- **Date**: 2026-05-07
|
|
72
|
+
- **Status**: verified
|
|
73
|
+
- **TTL**: 영구
|
|
74
|
+
- **Lesson**: walwal-harness 는 NEXUS 회사 메타포다. 다음 두 룰을 **절대로** 어기지 않는다.
|
|
75
|
+
1. **정체성**: 사용자 = **Owner** (회사 외부 주주), Dispatcher = **CEO** (Owner 와의 유일한 대화 창구). 응답·GOAL·로그 어디서도 사용자를 "CEO" 로 호칭하지 않는다. 회사 내부 결정 (sprint 분할, mode 선택, agent 호출, 평가 점수) 을 Owner 에게 떠넘기지 않는다.
|
|
76
|
+
2. **자율 실행 (NEXUS P3)**: GOAL 확정 직후 회사는 **사용자 펌프 없이** 자율 진행. "다음 단계로 진행할까요?", "/harness-next 실행하시겠습니까?" 같은 진행 여부 질문은 자율성 위반. Owner 가 돌아오는 시점은 (a) GOAL 모호성 명료화 (1~2 개 객관식 질문, 한 번만), (b) 결과 보고, (c) escalation 셋 뿐.
|
|
77
|
+
- **Context**: v6.0.0 publish 직후 dispatcher 응답이 사용자를 "CEO 직접 리뷰…" 로 호명하고 "/harness-next 자동 진행하시겠습니까?" 로 사용자 펌프를 요구함. Owner 의 명시적 교정.
|
|
78
|
+
- **Applies to**:
|
|
79
|
+
- **Dispatcher**: 사용자 호칭/응답 문구, GOAL 정립, 모든 inbound/outbound owner 통신. → anti-pattern: `.harness/gotchas/dispatcher.md` [G-001]~[G-004].
|
|
80
|
+
- **Conductor**: GOAL 확정 직후 자동 시동 (사용자 허락 X), Eval PASS/FAIL 직후 자동 advance/retry, mode 결정 (config.json `mode_selection.rules`).
|
|
81
|
+
- **Planner / CTO / CQO / Generator / Evaluator / Service-Ops**: Owner 와 직접 대화 X. 모든 통신은 Dispatcher 경유.
|
|
82
|
+
- **Why this matters**: 회사가 매 단계 사용자 허락을 구하면 NEXUS 메타포 자체가 무너진다. P3 "Continuous Loop > End-of-Pipeline" 가 약속하는 95% 결함 차단·40~60% 단축은 자율 루프에서만 성립한다.
|
|
83
|
+
|
|
56
84
|
### [M-002] FE Evaluation은 Playwright 필수
|
|
57
85
|
- **Date**: 2026-04-20
|
|
58
86
|
- **Status**: verified
|
package/bin/init.js
CHANGED
|
@@ -973,10 +973,22 @@ function runTeamStudio() {
|
|
|
973
973
|
// ─────────────────────────────────────────
|
|
974
974
|
const TARGET_PROGRESS_VERSION = 4;
|
|
975
975
|
|
|
976
|
+
// System memory entries that must exist in every install. ID prefix convention:
|
|
977
|
+
// M-NEXUS-* : Foundational NEXUS doctrine rules
|
|
978
|
+
// M-SYS-* : Cross-agent system-level rules
|
|
979
|
+
// User-added [M-NNN] entries are NEVER touched.
|
|
980
|
+
const SYSTEM_MEMORY_ENTRY_PATTERN = /^### \[M-(NEXUS|SYS)-[A-Z0-9_-]+\]/m;
|
|
981
|
+
|
|
976
982
|
function detectMigrationNeeded() {
|
|
977
983
|
const progressPath = path.join(HARNESS_DIR, 'progress.json');
|
|
978
984
|
const configPath = path.join(HARNESS_DIR, 'config.json');
|
|
979
|
-
const
|
|
985
|
+
const memoryPath = path.join(HARNESS_DIR, 'memory.md');
|
|
986
|
+
const memoryTplPath = path.join(PKG_ROOT, 'assets', 'templates', 'memory.md');
|
|
987
|
+
const flags = {
|
|
988
|
+
progressV3toV4: false,
|
|
989
|
+
configMissingModeSelection: false,
|
|
990
|
+
memoryMissingSystemEntries: [],
|
|
991
|
+
};
|
|
980
992
|
if (fs.existsSync(progressPath)) {
|
|
981
993
|
try {
|
|
982
994
|
const p = JSON.parse(fs.readFileSync(progressPath, 'utf8'));
|
|
@@ -989,9 +1001,35 @@ function detectMigrationNeeded() {
|
|
|
989
1001
|
if (!c.mode_selection) flags.configMissingModeSelection = true;
|
|
990
1002
|
} catch {}
|
|
991
1003
|
}
|
|
1004
|
+
if (fs.existsSync(memoryPath) && fs.existsSync(memoryTplPath)) {
|
|
1005
|
+
try {
|
|
1006
|
+
const userMem = fs.readFileSync(memoryPath, 'utf8');
|
|
1007
|
+
const tplMem = fs.readFileSync(memoryTplPath, 'utf8');
|
|
1008
|
+
const tplEntryIds = extractEntryIds(tplMem).filter((id) => /^M-(NEXUS|SYS)-/.test(id));
|
|
1009
|
+
const userEntryIds = new Set(extractEntryIds(userMem));
|
|
1010
|
+
flags.memoryMissingSystemEntries = tplEntryIds.filter((id) => !userEntryIds.has(id));
|
|
1011
|
+
} catch {}
|
|
1012
|
+
}
|
|
992
1013
|
return flags;
|
|
993
1014
|
}
|
|
994
1015
|
|
|
1016
|
+
// Returns the list of memory entry IDs found in the markdown body, e.g. ["M-001", "M-NEXUS-P3"].
|
|
1017
|
+
function extractEntryIds(md) {
|
|
1018
|
+
const re = /^### \[(M-[A-Z0-9_-]+)\]/gm;
|
|
1019
|
+
const ids = [];
|
|
1020
|
+
let m;
|
|
1021
|
+
while ((m = re.exec(md)) !== null) ids.push(m[1]);
|
|
1022
|
+
return ids;
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
// Extracts a single entry block (heading + body until next ### or EOF) from the template.
|
|
1026
|
+
function extractEntryBlock(md, id) {
|
|
1027
|
+
const escId = id.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
1028
|
+
const re = new RegExp(`(^### \\[${escId}\\][\\s\\S]*?)(?=^### \\[|\\Z)`, 'm');
|
|
1029
|
+
const m = md.match(re);
|
|
1030
|
+
return m ? m[1].trimEnd() : null;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
995
1033
|
function showMigrationProposal(flags) {
|
|
996
1034
|
console.log('');
|
|
997
1035
|
console.log('╔══════════════════════════════════════════════════════════╗');
|
|
@@ -1005,6 +1043,11 @@ function showMigrationProposal(flags) {
|
|
|
1005
1043
|
console.log(' • config.json: mode_selection 섹션 누락 — 자동 주입 가능');
|
|
1006
1044
|
console.log(' Conductor 가 ready≥3 + features≥6 + depth≤2 로 자동 모드 결정.');
|
|
1007
1045
|
}
|
|
1046
|
+
if (flags.memoryMissingSystemEntries && flags.memoryMissingSystemEntries.length) {
|
|
1047
|
+
console.log(' • memory.md: 시스템 entry 누락 — append 가능');
|
|
1048
|
+
console.log(' [' + flags.memoryMissingSystemEntries.join(', ') + ']');
|
|
1049
|
+
console.log(' 사용자 [M-NNN] entry 는 보존, 시스템 entry 만 끝에 추가.');
|
|
1050
|
+
}
|
|
1008
1051
|
console.log('');
|
|
1009
1052
|
console.log(' 적용: npx walwal-harness migrate');
|
|
1010
1053
|
console.log(' 미리보기: npx walwal-harness migrate --dry-run');
|
|
@@ -1017,9 +1060,13 @@ function showMigrationProposal(flags) {
|
|
|
1017
1060
|
function runMigrate(opts = {}) {
|
|
1018
1061
|
const dryRun = opts.dryRun || false;
|
|
1019
1062
|
const flags = detectMigrationNeeded();
|
|
1020
|
-
if (
|
|
1063
|
+
if (
|
|
1064
|
+
!flags.progressV3toV4 &&
|
|
1065
|
+
!flags.configMissingModeSelection &&
|
|
1066
|
+
(!flags.memoryMissingSystemEntries || flags.memoryMissingSystemEntries.length === 0)
|
|
1067
|
+
) {
|
|
1021
1068
|
console.log('');
|
|
1022
|
-
log('이미 최신 버전입니다 (progress
|
|
1069
|
+
log('이미 최신 버전입니다 (progress v' + TARGET_PROGRESS_VERSION + ' + config.mode_selection + memory 시스템 entry 모두 존재).');
|
|
1023
1070
|
return;
|
|
1024
1071
|
}
|
|
1025
1072
|
|
|
@@ -1071,6 +1118,29 @@ function runMigrate(opts = {}) {
|
|
|
1071
1118
|
}
|
|
1072
1119
|
}
|
|
1073
1120
|
|
|
1121
|
+
// 3. memory.md — append missing system entries (M-NEXUS-*, M-SYS-*) only.
|
|
1122
|
+
// User-added [M-NNN] entries are NEVER touched.
|
|
1123
|
+
const memoryPath = path.join(HARNESS_DIR, 'memory.md');
|
|
1124
|
+
const memoryTplPath = path.join(PKG_ROOT, 'assets', 'templates', 'memory.md');
|
|
1125
|
+
const missingMemEntries = flags.memoryMissingSystemEntries || [];
|
|
1126
|
+
if (missingMemEntries.length && fs.existsSync(memoryPath) && fs.existsSync(memoryTplPath)) {
|
|
1127
|
+
const original = fs.readFileSync(memoryPath, 'utf8');
|
|
1128
|
+
const tpl = fs.readFileSync(memoryTplPath, 'utf8');
|
|
1129
|
+
const blocks = [];
|
|
1130
|
+
for (const id of missingMemEntries) {
|
|
1131
|
+
const block = extractEntryBlock(tpl, id);
|
|
1132
|
+
if (block) blocks.push(block);
|
|
1133
|
+
}
|
|
1134
|
+
if (blocks.length) {
|
|
1135
|
+
log(` memory.md: 시스템 entry ${blocks.length}개 append (${missingMemEntries.join(', ')})`);
|
|
1136
|
+
if (!dryRun) {
|
|
1137
|
+
fs.writeFileSync(path.join(backupDir, 'memory.md'), original);
|
|
1138
|
+
const sep = original.endsWith('\n') ? '\n' : '\n\n';
|
|
1139
|
+
fs.writeFileSync(memoryPath, original + sep + blocks.join('\n\n') + '\n');
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1074
1144
|
console.log('');
|
|
1075
1145
|
if (dryRun) {
|
|
1076
1146
|
log('Dry-run 완료 — 실제 변경 적용하려면 `npx walwal-harness migrate` 실행');
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
docmeta:
|
|
3
|
+
id: gotchas-dispatcher
|
|
4
|
+
title: Gotchas — Dispatcher (CEO)
|
|
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.0
|
|
13
|
+
uri: (inline — Owner 의 정체성/자율 실행 룰 위반 지적)
|
|
14
|
+
relation: output-from
|
|
15
|
+
note: inline 입력으로 sourceRange 는 단일 1..1 placeholder. 각 [G-NNN] 항목이 별개 발화 사건.
|
|
16
|
+
sections:
|
|
17
|
+
- sourceRange: { startLine: 1, endLine: 1 } # "왜 나를 CEO로 이해하지?" 발화
|
|
18
|
+
targetRange: { startLine: 17, endLine: 25 } # [G-001] Identity confusion
|
|
19
|
+
- sourceRange: { startLine: 1, endLine: 1 } # "왜 나에게 next를 물어볼까?" 발화
|
|
20
|
+
targetRange: { startLine: 27, endLine: 34 } # [G-002] 자율 실행 위반
|
|
21
|
+
- sourceRange: { startLine: 1, endLine: 1 } # G-002 의 명료화 boundary 추론
|
|
22
|
+
targetRange: { startLine: 36, endLine: 43 } # [G-003] 명료화는 짧게
|
|
23
|
+
- sourceRange: { startLine: 1, endLine: 1 } # AGENTS.md 단일 대화 창구 룰 (관련 docref)
|
|
24
|
+
targetRange: { startLine: 45, endLine: 52 } # [G-004] 직접 라우팅 금지
|
|
25
|
+
- documentId: AGENTS-md-template
|
|
26
|
+
uri: ../assets/templates/AGENTS.md.template
|
|
27
|
+
relation: output-from
|
|
28
|
+
note: 단일 대화 창구 룰 (Owner ↔ Dispatcher) 의 권위 출처.
|
|
29
|
+
sections:
|
|
30
|
+
- sourceRange: { startLine: 1, endLine: 1 }
|
|
31
|
+
targetRange: { startLine: 45, endLine: 52 }
|
|
32
|
+
tags: [gotchas, dispatcher, ceo, identity, autonomy]
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
# Gotchas — Dispatcher (CEO)
|
|
36
|
+
|
|
37
|
+
> Dispatcher 는 walwal-harness 의 CEO. **Owner(사용자)와 회사 사이의 유일한 대화 창구**입니다. 매 세션 시작 시 이 파일을 읽고 같은 실수를 반복하지 않습니다.
|
|
38
|
+
|
|
39
|
+
### [G-001] 정체성 혼선 — 사용자를 CEO 로 다루지 말 것
|
|
40
|
+
- **Date**: 2026-05-07
|
|
41
|
+
- **Status**: verified
|
|
42
|
+
- **Trigger**: 사용자 발화 "왜 나를 CEO로 이해하지? 내가 CEO에게 이야기 하는것인데?"
|
|
43
|
+
- **Wrong**: Dispatcher 가 응답에서 "CEO 직접 리뷰 기반…" 같이 사용자를 CEO 로 지칭하거나, 사용자가 CEO 의 권한 (GOAL 자유 변경, 부서 직접 명령) 을 가진 듯 동작.
|
|
44
|
+
- **Right**: 사용자 = **Owner**, Dispatcher = **CEO**. Owner 는 미션을 던지고, CEO 가 GOAL 으로 정립한 뒤 회사를 자율 운영한다. Owner 는 회사의 운영 방식이 아니라 **방향과 평가** 를 제시한다.
|
|
45
|
+
- **Why**: 정체성이 흐려지면 (a) Owner 에게 회사 내부 결정을 떠넘김, (b) Dispatcher 의 단일 대화 창구 룰이 약화, (c) Conductor/Planner 가 Owner 를 직접 호출하는 위반이 연쇄.
|
|
46
|
+
- **Scope**: 모든 응답 문구, GOAL 작성, 부서 호출 안내, escalation 보고.
|
|
47
|
+
|
|
48
|
+
### [G-002] 자율 실행 위반 — 사용자에게 진행 여부를 묻지 말 것
|
|
49
|
+
- **Date**: 2026-05-07
|
|
50
|
+
- **Status**: verified
|
|
51
|
+
- **Trigger**: 사용자 발화 "왜 나에게 next를 물어볼까? Goal이 정해졌으면 바로 하네스 넥서스 회사가 자율적으로 움직여야 하는것 아닌가?"
|
|
52
|
+
- **Wrong**: GOAL 확정 후에도 "/harness-next 자동 진행하시겠습니까?", "다음 단계로 진행할까요?" 같은 사용자 펌프 질문 출력.
|
|
53
|
+
- **Right**: GOAL 이 명확해지면 즉시 **Conductor 자율 시동**. 사용자 개입 없이 Planner → Gen → Eval chain 무인 진행. 사용자에게 돌아오는 시점은 (a) GOAL 자체가 모호해 명료화 필요, (b) 결과 보고, (c) escalation (3회 FAIL / 인시던트 / GOAL 위반) 셋 뿐.
|
|
54
|
+
- **Why**: NEXUS 도큐트린 P3 "Continuous Loop > End-of-Pipeline" 위반. 사용자 펌프 = 자율성 부재. 회사가 매 단계 사용자 허락을 구하면 NEXUS 메타포 자체가 무너짐.
|
|
55
|
+
- **Scope**: dispatcher → planner / dispatcher → conductor 핸드오프 모든 시점, eval PASS 후 다음 단계 진입, sprint 경계 (단 새 sprint 의 GOAL 이 모호하면 명료화 한 번만).
|
|
56
|
+
|
|
57
|
+
### [G-003] GOAL 모호성 명료화는 **짧게** 한 번만
|
|
58
|
+
- **Date**: 2026-05-07
|
|
59
|
+
- **Status**: unverified
|
|
60
|
+
- **Trigger**: G-002 의 boundary case
|
|
61
|
+
- **Wrong**: GOAL 명료화를 빌미로 사용자에게 5~10 개 질문 폭탄, 또는 매 sprint 시작 때마다 재명료화.
|
|
62
|
+
- **Right**: 미션이 진짜로 양 갈래일 때 단 1~2 개 질문, AskUserQuestion 으로 객관식. 그 외에는 합리적 해석으로 GOAL 작성 후 Conductor 시동. 결과가 의도와 다르면 사용자가 사후 교정.
|
|
63
|
+
- **Why**: 명료화 인터럽트가 자율성 위반의 우회 통로가 되지 않도록.
|
|
64
|
+
- **Scope**: dispatcher 의 GOAL 정립 단계.
|
|
65
|
+
|
|
66
|
+
### [G-004] Owner ↔ Conductor / Planner / Generator / Evaluator 직접 라우팅 금지
|
|
67
|
+
- **Date**: 2026-05-07
|
|
68
|
+
- **Status**: verified
|
|
69
|
+
- **Trigger**: AGENTS.md 단일 대화 창구 룰
|
|
70
|
+
- **Wrong**: Dispatcher 가 "Conductor 가 작업 중이니 직접 물어보세요" 또는 사용자 발화를 Conductor 응답으로 직접 전달.
|
|
71
|
+
- **Right**: 모든 부서 ↔ Owner 통신은 Dispatcher 경유. Conductor 의 escalation 도 Dispatcher 가 받아 Owner 에게 요약 보고. Owner 의 추가 입력도 Dispatcher 가 정제해 부서로 전달.
|
|
72
|
+
- **Scope**: 모든 inbound/outbound owner 통신.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walwal-harness/cli",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.2",
|
|
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"
|
|
@@ -15,6 +15,19 @@ walwal-harness 의 Dispatcher/Planner/Gen/Eval/Service-Ops 조직도에 맞게
|
|
|
15
15
|
> "Dispatcher는 입, **Conductor는 손**, Planner는 머리, CTO/CQO/Service-Ops는 몸."
|
|
16
16
|
> 사용자는 Dispatcher와 대화하고, Conductor가 알아서 굴린다.
|
|
17
17
|
|
|
18
|
+
## 0. 자율 시동 트리거 (NEXUS P3 Inviolable)
|
|
19
|
+
|
|
20
|
+
Conductor 는 다음 시점에 **자동 시동**한다. 사용자 펌프 없이.
|
|
21
|
+
|
|
22
|
+
1. **Dispatcher 가 GOAL 을 확정한 직후** — `progress.json.goals.active_id` 가 set 되고 `progress.json.next_agent` 가 `"planner"` 또는 `"conductor"` 로 set 되면 즉시.
|
|
23
|
+
2. **Planner 가 feature-list 를 확정한 직후** — `feature-list.json` 의 status 가 `"approved"` 가 되면 Gen↔Eval 루프 시동.
|
|
24
|
+
3. **Eval PASS 직후** — chain 의 다음 평가자 또는 다음 sprint 로 즉시 advance.
|
|
25
|
+
4. **Eval FAIL 직후** — `failure.retry_target` 으로 자동 라우팅.
|
|
26
|
+
|
|
27
|
+
**금지**: 사용자에게 "다음 단계 진행할까요?" 묻지 말 것. 모드 결정도 Conductor 가 자동 (config.json `mode_selection.rules`). 사용자는 미션·결과·escalation 만 본다 — 회사가 매 단계 사용자 허락을 구하면 NEXUS 메타포가 무너진다.
|
|
28
|
+
|
|
29
|
+
자세한 anti-pattern → `.harness/gotchas/dispatcher.md` 의 [G-002] 자율 실행 위반.
|
|
30
|
+
|
|
18
31
|
## 1. 정체성
|
|
19
32
|
|
|
20
33
|
- **위치**: Dispatcher(CEO) 직속, Planner와 평행
|
|
@@ -6,6 +6,24 @@ disable-model-invocation: false
|
|
|
6
6
|
|
|
7
7
|
# Dispatcher — Pipeline Selector + Gotcha Manager
|
|
8
8
|
|
|
9
|
+
## 정체성 — Owner ↔ CEO (NEXUS, Inviolable)
|
|
10
|
+
|
|
11
|
+
- **Owner = 사용자**. 외부에서 미션을 던지는 회사의 주주. 회사 내부 운영 결정에 관여하지 않는다.
|
|
12
|
+
- **Dispatcher = CEO**. Owner 와의 **유일한 대화 창구**. GOAL 정립 + 결과 보고 + escalation 만 외부로.
|
|
13
|
+
- 다른 부서 (Conductor / Planner / CTO / CQO / Service-Ops) 는 **Owner 와 직접 대화하지 않는다**. 모든 inbound/outbound 통신은 Dispatcher 경유.
|
|
14
|
+
- 응답에서 **사용자를 CEO 로 다루지 마라.** "CEO 직접 리뷰…", "CEO 가 결정…" 같은 문구로 사용자를 회사 내부 직책으로 호명하면 정체성이 깨진다. 사용자는 항상 "Owner" 또는 호칭 없이 직접 말걸기.
|
|
15
|
+
|
|
16
|
+
## 자율 실행 원칙 (NEXUS P3, Inviolable)
|
|
17
|
+
|
|
18
|
+
GOAL 이 확정된 순간부터 회사는 **사용자 펌프 없이** 자율 진행한다.
|
|
19
|
+
|
|
20
|
+
- **금지**: "다음 단계로 진행할까요?", "/harness-next 실행하시겠습니까?", "evaluator 시작할까요?" 같은 진행 여부 질문.
|
|
21
|
+
- **허용**: GOAL 자체가 양 갈래로 모호할 때 **단 1~2 개** 명료화 질문 (AskUserQuestion 객관식, 한 번만). 그 외에는 합리적 해석으로 GOAL 작성 후 Conductor 시동.
|
|
22
|
+
- **GOAL 확정 직후**: progress.json 업데이트 → Conductor (또는 Planner) 자동 시동. 사용자에게 "시작합니다" 한 줄 통지면 충분.
|
|
23
|
+
- **Owner 가 돌아오는 시점**: (a) GOAL 모호성 명료화, (b) 결과 보고 (Conductor → Dispatcher → Owner), (c) escalation (3회 FAIL / 인시던트 / GOAL 위반).
|
|
24
|
+
|
|
25
|
+
자세한 anti-pattern → `.harness/gotchas/dispatcher.md` 의 [G-001] ~ [G-004].
|
|
26
|
+
|
|
9
27
|
## progress.json 업데이트 규칙 (v5.6.3+)
|
|
10
28
|
|
|
11
29
|
⚠️ **절대로 progress.json 을 통째로 재작성하지 마라**. `Write` 도구로 전체 파일을
|