@dmsdc-ai/aigentry-deliberation 0.0.20 → 0.0.22

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
@@ -31,6 +31,8 @@ npx @dmsdc-ai/aigentry-deliberation install
31
31
  2. npm 의존성 설치
32
32
  3. `~/.claude/.mcp.json`에 MCP 서버 자동 등록
33
33
  4. Claude Code 재시작하면 바로 사용 가능
34
+ 5. Gemini CLI MCP 서버 자동 등록 (`~/.gemini/settings.json`)
35
+ 6. deliberation-gate 스킬 자동 설치 (`~/.claude/skills/deliberation-gate/`)
34
36
 
35
37
  ### 기타 설치 방법
36
38
 
@@ -53,6 +55,8 @@ cd aigentry-deliberation && npm install && node install.js
53
55
  npx @dmsdc-ai/aigentry-deliberation uninstall
54
56
  ```
55
57
 
58
+ MCP 서버 등록 해제 + 설치 파일 삭제 + 스킬 파일 정리까지 자동 처리됩니다.
59
+
56
60
  ## Forum Demo
57
61
 
58
62
  Deliberation이 완료되면 결과를 시각화하는 Forum View를 생성합니다.
@@ -68,6 +72,16 @@ Deliberation이 완료되면 결과를 시각화하는 Forum View를 생성합
68
72
  open demo/forum/index.html
69
73
  ```
70
74
 
75
+ ## Diagnostics
76
+
77
+ MCP 연결 문제 자동 진단:
78
+
79
+ ```bash
80
+ npx @dmsdc-ai/aigentry-deliberation doctor
81
+ ```
82
+
83
+ Claude Code, Codex CLI, Gemini CLI의 MCP 설정을 자동 점검하고 문제를 진단합니다.
84
+
71
85
  ## MCP Tools
72
86
 
73
87
  | Tool | Description |
@@ -107,6 +121,28 @@ open demo/forum/index.html
107
121
  | `researcher` | Data, benchmarks, references |
108
122
  | `free` | No role constraint (default) |
109
123
 
124
+ ### deliberation-gate (Superpowers Integration)
125
+
126
+ Inserts multi-AI verification gates at key [superpowers](https://github.com/obra/superpowers) workflow decision points.
127
+
128
+ **Scenarios:**
129
+ - **brainstorming** → multi-AI design validation before writing plans
130
+ - **code-review** → multi-AI review via `deliberation_request_review`
131
+ - **debugging** → multi-AI hypothesis verification when stuck
132
+
133
+ **Trigger:** Semi-automatic — skill recommends deliberation, user approves.
134
+
135
+ **Fallback:** MCP 미설치 시 self-criticism 기반 자가 검증으로 대체 (Silver 등급). MCP 설치 시 멀티-AI 토론 (Gold 등급).
136
+
137
+ **Install:** `npx @dmsdc-ai/aigentry-deliberation install` 실행 시 자동 설치됩니다.
138
+
139
+ 수동 설치:
140
+ ```bash
141
+ cp skills/deliberation-gate/SKILL.md ~/.claude/skills/deliberation-gate/SKILL.md
142
+ ```
143
+
144
+ **RFC:** [Prerequisites header for tool-dependent skills](https://github.com/obra/superpowers/issues/589)
145
+
110
146
  ## aigentry Ecosystem
111
147
 
112
148
  aigentry-deliberation is one component of the unified aigentry platform. All packages work together to make AI decisions transparent and auditable.
@@ -509,15 +509,6 @@ class DevToolsMcpAdapter extends BrowserControlPort {
509
509
  }
510
510
  }
511
511
 
512
- const sendResult = { ok: true };
513
-
514
- if (!sendResult.ok) {
515
- return makeResult(false, null, {
516
- code: "SEND_FAILED",
517
- message: `Send button not found: ${binding.selectors.sendButton}`,
518
- });
519
- }
520
-
521
512
  sent.add(turnId);
522
513
  return makeResult(true, { turnId, sent: true });
523
514
  } catch (err) {
package/index.js CHANGED
@@ -948,7 +948,7 @@ async function ensureCdpAvailable() {
948
948
 
949
949
  const launchArgs = [
950
950
  "--remote-debugging-port=9222",
951
- "--remote-allow-origins=*",
951
+ "--remote-allow-origins=http://127.0.0.1:9222",
952
952
  `--user-data-dir=${cdpDataDir}`,
953
953
  `--profile-directory=${profileDir}`,
954
954
  "--no-first-run",
@@ -965,7 +965,7 @@ async function ensureCdpAvailable() {
965
965
  }
966
966
 
967
967
  // Wait for Chrome to initialize CDP
968
- sleepMs(5000);
968
+ await new Promise(resolve => setTimeout(resolve, 5000));
969
969
 
970
970
  // Retry CDP connection after launch
971
971
  for (const endpoint of endpoints) {
@@ -2739,9 +2739,24 @@ server.tool(
2739
2739
 
2740
2740
  const speaker = state.current_speaker;
2741
2741
  const { transport, profile, reason } = resolveTransportForSpeaker(state, speaker);
2742
- const guidance = formatTransportGuidance(transport, state, speaker);
2743
2742
  const turnId = state.pending_turn_id || null;
2744
2743
 
2744
+ // ── Self-speaker detection ──
2745
+ // If the current speaker is the same CLI as the orchestrator (caller),
2746
+ // cli_auto_turn would recursively spawn the same process and timeout.
2747
+ // Instead, instruct the orchestrator to respond directly.
2748
+ const callerSpeaker = detectCallerSpeaker();
2749
+ const isSelfSpeaker = callerSpeaker && speaker === callerSpeaker && transport === "cli_respond";
2750
+
2751
+ let guidance;
2752
+ if (isSelfSpeaker) {
2753
+ guidance = `🟢 **본인 턴입니다.** 당신(${speaker})이 현재 speaker입니다.\n\n` +
2754
+ `직접 응답을 작성하여 \`deliberation_respond(session_id: "${state.id}", speaker: "${speaker}", content: "...")\`로 제출하세요.\n\n` +
2755
+ `⚠️ **cli_auto_turn 사용 금지**: 자기 자신을 재귀 호출하면 타임아웃이 발생합니다. 반드시 직접 deliberation_respond를 사용하세요.`;
2756
+ } else {
2757
+ guidance = formatTransportGuidance(transport, state, speaker);
2758
+ }
2759
+
2745
2760
  let extra = "";
2746
2761
 
2747
2762
  if (transport === "browser_auto") {
@@ -2963,6 +2978,17 @@ server.tool(
2963
2978
  return { content: [{ type: "text", text: `speaker "${speaker}"는 CLI 타입이 아닙니다 (transport: ${transport}). 브라우저 speaker는 deliberation_browser_auto_turn을 사용하세요.` }] };
2964
2979
  }
2965
2980
 
2981
+ // Block recursive self-spawn: if the speaker is the same CLI as the caller,
2982
+ // spawning it would create infinite recursion and timeout.
2983
+ const callerSpeaker = detectCallerSpeaker();
2984
+ if (callerSpeaker && speaker === callerSpeaker) {
2985
+ return { content: [{ type: "text", text:
2986
+ `⚠️ **재귀 호출 차단**: speaker "${speaker}"는 현재 오케스트레이터와 동일한 CLI입니다.\n\n` +
2987
+ `cli_auto_turn으로 자기 자신을 spawn하면 타임아웃이 발생합니다.\n` +
2988
+ `직접 응답을 작성하여 \`deliberation_respond(session_id: "${resolved}", speaker: "${speaker}", content: "...")\`로 제출하세요.`
2989
+ }] };
2990
+ }
2991
+
2966
2992
  const hint = CLI_INVOCATION_HINTS[speaker];
2967
2993
  if (!hint) {
2968
2994
  return { content: [{ type: "text", text: `speaker "${speaker}"에 대한 CLI 호출 정보가 없습니다. CLI_INVOCATION_HINTS에 등록되지 않은 speaker입니다.` }] };
@@ -3098,7 +3124,8 @@ server.tool(
3098
3124
  const { transport } = resolveTransportForSpeaker(state, speaker);
3099
3125
  if (transport === "cli_respond" || transport === "browser_auto") {
3100
3126
  // Check if caller is the same speaker (legitimate self-response) or an impersonator
3101
- const callerIsSpeaker = (speaker === "claude"); // orchestrator can only legitimately respond as "claude"
3127
+ const callerSpeaker = detectCallerSpeaker();
3128
+ const callerIsSpeaker = callerSpeaker && (speaker === callerSpeaker);
3102
3129
  if (!callerIsSpeaker) {
3103
3130
  return {
3104
3131
  content: [{
@@ -3422,15 +3449,36 @@ server.tool(
3422
3449
  // ── Request Review (auto-review) ───────────────────────────────
3423
3450
 
3424
3451
  function invokeCliReviewer(command, prompt, timeoutMs) {
3425
- const args = ["-p", prompt, "--no-input"];
3452
+ const hint = CLI_INVOCATION_HINTS[command];
3453
+ let args;
3454
+ let opts = { encoding: "utf-8", timeout: timeoutMs, stdio: ["pipe", "pipe", "pipe"], maxBuffer: 5 * 1024 * 1024, windowsHide: true };
3455
+ const env = { ...process.env };
3456
+
3457
+ switch (command) {
3458
+ case "claude":
3459
+ if (hint?.envPrefix?.includes("CLAUDECODE=")) delete env.CLAUDECODE;
3460
+ args = ["-p", "--output-format", "text", "--no-input"];
3461
+ opts.input = prompt;
3462
+ opts.stdio = ["pipe", "pipe", "pipe"];
3463
+ break;
3464
+ case "codex":
3465
+ args = ["exec", prompt];
3466
+ opts.stdio = ["ignore", "pipe", "pipe"];
3467
+ break;
3468
+ case "gemini":
3469
+ args = ["-p", prompt];
3470
+ opts.stdio = ["ignore", "pipe", "pipe"];
3471
+ break;
3472
+ default: {
3473
+ const flags = hint?.flags ? hint.flags.split(/\s+/).filter(Boolean) : ["-p"];
3474
+ args = [...flags, prompt];
3475
+ opts.stdio = ["ignore", "pipe", "pipe"];
3476
+ break;
3477
+ }
3478
+ }
3479
+
3426
3480
  try {
3427
- const result = execFileSync(command, args, {
3428
- encoding: "utf-8",
3429
- timeout: timeoutMs,
3430
- stdio: ["ignore", "pipe", "pipe"],
3431
- maxBuffer: 5 * 1024 * 1024,
3432
- windowsHide: true,
3433
- });
3481
+ const result = execFileSync(command, args, { ...opts, env });
3434
3482
  return { ok: true, response: result.trim() };
3435
3483
  } catch (error) {
3436
3484
  if (error && error.killed) {
package/install.js CHANGED
@@ -13,6 +13,7 @@
13
13
  * 3. Registers MCP server in ~/.claude/.mcp.json (Claude Code)
14
14
  * 4. Registers MCP server in ~/.gemini/settings.json (Gemini CLI)
15
15
  * 5. Ready to use — next Claude Code or Gemini CLI session will auto-load
16
+ * 6. 스킬 파일 설치 (~/.claude/skills/deliberation-gate/SKILL.md)
16
17
  */
17
18
 
18
19
  import { execSync } from "node:child_process";
@@ -28,6 +29,10 @@ const INSTALL_DIR = IS_WIN
28
29
  : path.join(HOME, ".local", "lib", "mcp-deliberation");
29
30
  const MCP_CONFIG = path.join(HOME, ".claude", ".mcp.json");
30
31
  const GEMINI_CONFIG = path.join(HOME, ".gemini", "settings.json");
32
+ const SKILL_SRC = path.join(__dirname, "skills", "deliberation-gate", "SKILL.md");
33
+ const SKILL_DEST_DIR = path.join(HOME, ".claude", "skills", "deliberation-gate");
34
+ const SKILL_DEST = path.join(SKILL_DEST_DIR, "SKILL.md");
35
+ const MANIFEST_PATH = path.join(INSTALL_DIR, ".install-manifest.json");
31
36
 
32
37
  /** Normalize path to forward slashes for JSON config (Windows backslash → forward slash) */
33
38
  function toForwardSlash(p) {
@@ -175,12 +180,53 @@ function install() {
175
180
  } catch { /* ignore on Windows */ }
176
181
  }
177
182
 
178
- // Step 6: Preserve existing config
183
+ // Step 6b: Preserve existing config
179
184
  const configPath = path.join(INSTALL_DIR, "config.json");
180
185
  if (!fs.existsSync(configPath)) {
181
186
  fs.writeFileSync(configPath, JSON.stringify({}, null, 2));
182
187
  }
183
188
 
189
+ // Step 7: Deploy deliberation-gate skill
190
+ log("🎓 deliberation-gate 스킬 파일 설치...");
191
+ if (!fs.existsSync(SKILL_SRC)) {
192
+ log(" ⚠️ 스킬 소스 파일 없음, 스킵: " + SKILL_SRC);
193
+ } else {
194
+ try {
195
+ fs.mkdirSync(SKILL_DEST_DIR, { recursive: true });
196
+ let shouldCopy = true;
197
+ if (fs.existsSync(SKILL_DEST) && !FORCE) {
198
+ const existing = fs.readFileSync(SKILL_DEST, "utf-8");
199
+ const incoming = fs.readFileSync(SKILL_SRC, "utf-8");
200
+ if (existing === incoming) {
201
+ log(" → 이미 최신 상태, 스킵");
202
+ shouldCopy = false;
203
+ } else {
204
+ fs.copyFileSync(SKILL_DEST, SKILL_DEST + ".backup");
205
+ log(" → 기존 파일 백업: SKILL.md.backup");
206
+ }
207
+ }
208
+ if (shouldCopy) {
209
+ fs.copyFileSync(SKILL_SRC, SKILL_DEST);
210
+ log(" → " + SKILL_DEST);
211
+ }
212
+ } catch (err) {
213
+ log(` ⚠️ 스킬 설치 실패: ${err.message}`);
214
+ }
215
+ }
216
+
217
+ // Write install manifest
218
+ try {
219
+ const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "package.json"), "utf-8"));
220
+ const manifest = {
221
+ version: pkg.version,
222
+ installedAt: new Date().toISOString(),
223
+ skills: [SKILL_DEST],
224
+ };
225
+ fs.writeFileSync(MANIFEST_PATH, JSON.stringify(manifest, null, 2));
226
+ } catch (err) {
227
+ log(` ⚠️ manifest 작성 실패: ${err.message}`);
228
+ }
229
+
184
230
  // Done
185
231
  console.log("\n✅ 설치 완료!\n");
186
232
  console.log(" 다음 단계:");
@@ -191,6 +237,7 @@ function install() {
191
237
 
192
238
  // Entry point
193
239
  const args = process.argv.slice(2);
240
+ const FORCE = args.includes("--force");
194
241
  if (args.includes("--help") || args.includes("-h")) {
195
242
  console.log(`
196
243
  Deliberation MCP Server Installer
@@ -202,10 +249,18 @@ Usage:
202
249
  Options:
203
250
  --help, -h 이 도움말 표시
204
251
  --uninstall 서버 제거
252
+ --force 기존 스킬 파일 비교 없이 강제 덮어쓰기
253
+
254
+ 기능:
255
+ - 서버 파일을 설치 경로에 복사
256
+ - npm 의존성 설치
257
+ - Claude Code / Gemini CLI MCP 서버 등록
258
+ - 스킬 파일 설치 (~/.claude/skills/deliberation-gate/SKILL.md)
205
259
 
206
260
  설치 경로: ${INSTALL_DIR}
207
261
  MCP 설정: ${MCP_CONFIG}
208
262
  Gemini: ${GEMINI_CONFIG}
263
+ 스킬 경로: ${SKILL_DEST}
209
264
  `);
210
265
  } else if (args.includes("--uninstall") || args.includes("uninstall")) {
211
266
  console.log("\n🗑️ Deliberation MCP Server 제거\n");
@@ -234,6 +289,39 @@ Gemini: ${GEMINI_CONFIG}
234
289
  } catch { /* ignore */ }
235
290
  }
236
291
 
292
+ // Remove skill files tracked by manifest (or fall back to default path)
293
+ let skillsToRemove = [SKILL_DEST];
294
+ const manifestFile = path.join(INSTALL_DIR, ".install-manifest.json");
295
+ if (fs.existsSync(manifestFile)) {
296
+ try {
297
+ const manifest = JSON.parse(fs.readFileSync(manifestFile, "utf-8"));
298
+ if (Array.isArray(manifest.skills) && manifest.skills.length > 0) {
299
+ skillsToRemove = manifest.skills;
300
+ }
301
+ } catch { /* use default */ }
302
+ }
303
+ for (const skillPath of skillsToRemove) {
304
+ if (fs.existsSync(skillPath)) {
305
+ try {
306
+ fs.rmSync(skillPath, { force: true });
307
+ log(`스킬 파일 삭제: ${skillPath}`);
308
+ const backupPath = skillPath + ".backup";
309
+ if (fs.existsSync(backupPath)) {
310
+ log(` 💡 백업 파일이 남아 있습니다: ${backupPath}`);
311
+ log(` 복원하려면: cp "${backupPath}" "${skillPath}"`);
312
+ }
313
+ // Remove directory if empty
314
+ const dir = path.dirname(skillPath);
315
+ if (fs.existsSync(dir) && fs.readdirSync(dir).length === 0) {
316
+ fs.rmdirSync(dir);
317
+ log(`빈 스킬 디렉토리 삭제: ${dir}`);
318
+ }
319
+ } catch (err) {
320
+ log(` ⚠️ 스킬 파일 삭제 실패: ${err.message}`);
321
+ }
322
+ }
323
+ }
324
+
237
325
  // Remove install directory
238
326
  if (fs.existsSync(INSTALL_DIR)) {
239
327
  fs.rmSync(INSTALL_DIR, { recursive: true, force: true });
package/observer.js CHANGED
@@ -261,7 +261,9 @@ function createServer(port) {
261
261
  const pathname = url.pathname;
262
262
 
263
263
  // CORS
264
- res.setHeader("Access-Control-Allow-Origin", "*");
264
+ const origin = req.headers.origin || "";
265
+ const allowedOrigins = [`http://127.0.0.1:${port}`, `http://localhost:${port}`];
266
+ res.setHeader("Access-Control-Allow-Origin", allowedOrigins.includes(origin) ? origin : allowedOrigins[0]);
265
267
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
266
268
  res.setHeader("Access-Control-Allow-Headers", "Content-Type");
267
269
 
@@ -377,7 +379,13 @@ function createServer(port) {
377
379
 
378
380
  req.on("close", () => {
379
381
  const clients = sseClients.get(sessionId) || [];
380
- sseClients.set(sessionId, clients.filter(c => c !== res));
382
+ const remaining = clients.filter(c => c !== res);
383
+ if (remaining.length === 0) {
384
+ sseClients.delete(sessionId);
385
+ sessionSnapshots.delete(sessionId);
386
+ } else {
387
+ sseClients.set(sessionId, remaining);
388
+ }
381
389
  });
382
390
  return;
383
391
  }
@@ -468,7 +476,7 @@ const server = createServer(port);
468
476
  // Poll every 1 second
469
477
  const pollInterval = setInterval(pollSessions, 1000);
470
478
 
471
- server.listen(port, () => {
479
+ server.listen(port, "127.0.0.1", () => {
472
480
  console.log(`Deliberation Observer running at http://localhost:${port}`);
473
481
  console.log(` Dashboard: http://localhost:${port}/`);
474
482
  console.log(` API: http://localhost:${port}/api/sessions`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dmsdc-ai/aigentry-deliberation",
3
- "version": "0.0.20",
3
+ "version": "0.0.22",
4
4
  "description": "MCP Deliberation Server — Multi-session AI deliberation with smart speaker ordering and persona roles",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -14,7 +14,7 @@ if (!sessionId) {
14
14
  }
15
15
 
16
16
  const HOME = process.env.HOME || process.env.USERPROFILE || "";
17
- const stateDir = path.join(HOME, ".local", "state", "mcp-deliberation", project);
17
+ const stateDir = path.join(HOME, ".local", "lib", "mcp-deliberation", "state", project);
18
18
  const stateFile = path.join(stateDir, `${sessionId}.json`);
19
19
 
20
20
  const BOLD = "\x1b[1m";
@@ -176,3 +176,8 @@ bash deliberation-monitor.sh --tmux
176
176
  4. 실시간 sync 파일은 state 디렉토리에 저장되며 완료 시 자동 삭제됨 (프로젝트 루트 오염 없음)
177
177
  5. `Transport closed` 발생 시 현재 CLI 세션 재시작 후 재시도 (stdio 연결은 세션 바인딩)
178
178
  6. 멀티 세션 운영 중 `pkill -f mcp-deliberation` 사용 금지 (다른 세션 연결까지 끊길 수 있음)
179
+
180
+ ## 관련 스킬
181
+
182
+ - **deliberation-gate**: superpowers 워크플로우 통합 스킬. brainstorming/code-review/debugging 의사결정 지점에 멀티-AI 검증 게이트를 삽입합니다. `~/.claude/skills/deliberation-gate/SKILL.md`에 설치.
183
+ - **deliberation-executor**: deliberation 합의안을 실제 코드 구현으로 전환하는 실행 전용 스킬.
@@ -0,0 +1,212 @@
1
+ ---
2
+ name: deliberation-gate
3
+ description: |
4
+ Use after brainstorming produces design doc, after code-review produces feedback,
5
+ when debugging hits dead end with failed hypotheses, or when user says
6
+ "deliberate this", "토론해줘", "검증해줘", "멀티-AI 리뷰", "multi-AI verify"
7
+ version: 0.1.0
8
+ prerequisites:
9
+ mcp: ["aigentry-deliberation"]
10
+ fallback: self-criticism
11
+ ---
12
+
13
+ # Deliberation Gate — Multi-AI Verification for Superpowers Workflows
14
+
15
+ Insert multi-AI deliberation gates at key decision points in superpowers workflow chains.
16
+ Uses aigentry-deliberation MCP tools to orchestrate structured debate between multiple AI systems.
17
+
18
+ **Semi-automatic**: Recommends deliberation at decision points. User approves before starting.
19
+
20
+ ## Context Detection
21
+
22
+ Detect the current workflow context by checking these signals IN ORDER:
23
+
24
+ | Priority | Signal | Context |
25
+ |----------|--------|---------|
26
+ | 1 | User says "deliberate", "토론", "debate", "검증", "멀티-AI" | explicit |
27
+ | 2 | Design doc recently written in session (docs/plans/*-design.md) | brainstorming |
28
+ | 3 | git diff output, PR number, or code review feedback in conversation | code-review |
29
+ | 4 | Error traces + failed hypotheses / "root cause" in conversation | debugging |
30
+ | 5 | None of above | general |
31
+
32
+ ### Scenario Preset Map
33
+
34
+ | Context | preset | rounds | roles | MCP path |
35
+ |---------|--------|--------|-------|----------|
36
+ | brainstorming | brainstorm | 2 | critic, implementer, researcher | deliberation_start → route_turn loop → synthesize |
37
+ | code-review | review | 1 | critic, implementer | deliberation_request_review (lightweight) |
38
+ | debugging | research | 2 | researcher, implementer, critic | deliberation_start → route_turn loop → synthesize |
39
+ | general | balanced | 3 | user-selected via AskUserQuestion | deliberation_start → route_turn loop → synthesize |
40
+
41
+ ## Recommendation Protocol (Semi-Automatic)
42
+
43
+ When you detect a decision point, recommend deliberation to the user.
44
+
45
+ ### Step 1: Detect and Announce
46
+
47
+ Announce the detected context:
48
+
49
+ > 🔔 **멀티-AI 검증 추천** — [context] 시나리오 감지
50
+ >
51
+ > 이 [설계안/코드 리뷰/디버깅 가설]을 다른 AI의 관점으로 검증하면 더 견고해질 수 있습니다.
52
+
53
+ ### Step 2: Ask User
54
+
55
+ Use AskUserQuestion to get approval:
56
+
57
+ ```
58
+ AskUserQuestion:
59
+ question: "이 [artifact]을 멀티-AI 토론으로 검증할까요?"
60
+ header: "멀티-AI 검증"
61
+ options:
62
+ - label: "시작 (Recommended)"
63
+ description: "[preset] preset, [N]라운드, [roles] 역할로 deliberation 시작"
64
+ - label: "설정 변경 후 시작"
65
+ description: "preset, rounds, roles를 직접 선택"
66
+ - label: "건너뛰기"
67
+ description: "deliberation 없이 원래 워크플로우 계속"
68
+ ```
69
+
70
+ ### Step 3: On Decline
71
+
72
+ If user chooses "건너뛰기":
73
+ - Do NOT persist or re-ask
74
+ - Continue the original workflow immediately
75
+ - No penalty, no warning
76
+
77
+ ## Deliberation Execution
78
+
79
+ When user approves, execute this sequence:
80
+
81
+ ### Standard Path (brainstorming, debugging, general)
82
+
83
+ 1. **Speaker discovery**: `deliberation_speaker_candidates` → get available CLI + browser speakers
84
+ 2. **Speaker selection**: `AskUserQuestion(multiSelect: true)` → user selects which speakers to include
85
+ 3. **Start deliberation**: `deliberation_start`
86
+ - `topic`: the artifact being validated (design summary / error description + hypotheses / user's question)
87
+ - `speakers`: user-selected list
88
+ - `speaker_roles`: from scenario preset map above
89
+ - `rounds`: from scenario preset map above
90
+ - `ordering_strategy`: "auto"
91
+ - `role_preset`: from scenario preset map above
92
+ 4. **Turn loop**: For each turn:
93
+ - Call `deliberation_route_turn` — it auto-detects the correct transport
94
+ - **Self-speaker** (you are the current speaker): Compose your response based on your role, submit via `deliberation_respond(speaker: "claude", content: "...")`
95
+ - **Other CLI speaker**: `deliberation_route_turn` will guide to `deliberation_cli_auto_turn` which spawns the actual CLI
96
+ - **Browser speaker**: `deliberation_route_turn` will auto-execute via CDP
97
+ 5. **Synthesize**: After all rounds complete, call `deliberation_synthesize` with a summary of the consensus
98
+ 6. **Apply synthesis**: Follow the Integration Rules below
99
+
100
+ ### Lightweight Path (code-review only)
101
+
102
+ 1. **Speaker discovery**: `deliberation_speaker_candidates` → get available speakers
103
+ 2. **Reviewer selection**: `AskUserQuestion(multiSelect: true)` → user selects reviewers
104
+ 3. **Request review**: `deliberation_request_review`
105
+ - `context`: the diff or code under review
106
+ - `question`: "이 코드 변경사항을 리뷰해주세요. 버그, 설계 문제, 보안 취약점을 중심으로."
107
+ - `reviewers`: user-selected list
108
+ - `mode`: "sync"
109
+ - `deadline_ms`: 120000
110
+ 4. **Apply results**: Follow the Integration Rules below
111
+
112
+ ## Synthesis Integration Rules
113
+
114
+ ### brainstorming → design doc update
115
+
116
+ After deliberation on a design:
117
+ 1. Read the synthesis from `deliberation_synthesize`
118
+ 2. Append a `## 멀티-AI 합의` section to the design doc with:
119
+ - **합의 사항**: Key agreements from all participants
120
+ - **이견**: Dissenting points (if any)
121
+ - **권장 변경**: Concrete changes recommended by consensus
122
+ 3. Apply the agreed changes to the design document
123
+ 4. Continue to `writing-plans` skill with the updated design
124
+
125
+ ### code-review → receiving-code-review
126
+
127
+ After multi-AI code review:
128
+ 1. Parse review results into severity categories:
129
+ - **Critical**: Must fix before merge
130
+ - **Major**: Should fix
131
+ - **Minor**: Optional improvements
132
+ 2. Present the categorized feedback to user
133
+ 3. Continue to `receiving-code-review` skill workflow
134
+
135
+ ### debugging → hypothesis reordering
136
+
137
+ After deliberation on debugging hypotheses:
138
+ 1. Extract the consensus hypothesis ranking from synthesis
139
+ 2. Update the debugging state:
140
+ - Move consensus-top hypothesis to position 1
141
+ - Mark disproven hypotheses as eliminated
142
+ - Add any new hypotheses suggested by other AIs
143
+ 3. Resume `systematic-debugging` with the new priorities
144
+
145
+ ### general → user-directed
146
+
147
+ For explicit or general deliberation:
148
+ 1. Present the synthesis summary to user
149
+ 2. Ask how to proceed with the consensus
150
+ 3. Follow user's direction
151
+
152
+ ## MCP 미설치 시 Fallback (Graceful Degradation)
153
+
154
+ deliberation MCP 도구(`deliberation_start`, `deliberation_speaker_candidates` 등)가 사용 불가능할 경우:
155
+
156
+ ### 감지 방법
157
+ - MCP 도구 호출 시 "tool not found" 또는 연결 실패 에러 발생
158
+ - `deliberation_speaker_candidates` 호출이 실패하면 MCP 미설치로 판단
159
+
160
+ ### Fallback 프로토콜
161
+
162
+ 1. **안내**: AskUserQuestion으로 상황 설명
163
+ ```
164
+ question: "멀티-AI 검증 MCP 서버가 감지되지 않았습니다. 단일 모델 자가 검증으로 대체할까요?"
165
+ options:
166
+ - label: "자가 검증 진행"
167
+ description: "3관점 self-criticism으로 검증 (Silver 등급)"
168
+ - label: "MCP 설치 안내"
169
+ description: "npx @dmsdc-ai/aigentry-deliberation install 실행 방법 안내"
170
+ - label: "건너뛰기"
171
+ description: "검증 없이 원래 워크플로우 계속"
172
+ ```
173
+
174
+ 2. **Self-Criticism 실행** (자가 검증 선택 시):
175
+ - 동일 artifact에 대해 3가지 관점으로 순차 분석:
176
+ - **비판적 분석가**: 약점, 리스크, 누락된 고려사항
177
+ - **현실적 실행가**: 구현 가능성, 비용, 복잡도
178
+ - **리서처**: 대안, 선례, 데이터 기반 근거
179
+ - 3관점 결과를 종합하여 합의 포맷으로 출력
180
+
181
+ 3. **투명성 라벨링**:
182
+ - 모든 검증 결과에 출처 라벨 필수 표시:
183
+ - `🥇 Verification: Multi-AI Deliberation (Gold)` — 실제 멀티-AI 토론 결과
184
+ - `🥈 Verification: Self-Criticism (Silver)` — 단일 모델 자가 검증 결과
185
+ - 라벨은 합의 섹션 상단에 표시
186
+
187
+ ### MCP 설치 안내 (선택 시)
188
+ ```
189
+ npx @dmsdc-ai/aigentry-deliberation install
190
+ ```
191
+ 설치 후 Claude Code 세션을 재시작하면 멀티-AI 검증이 활성화됩니다.
192
+
193
+ ## Anti-Patterns (NEVER)
194
+
195
+ 1. **NEVER skip user approval** — Always use AskUserQuestion before starting deliberation. This is a HARD GATE.
196
+ 2. **NEVER fabricate speaker responses** — Use `deliberation_route_turn` for other speakers. Never write responses on behalf of codex, gemini, or any other speaker. The MCP server blocks this.
197
+ 3. **NEVER use cli_auto_turn for self-speaker** — If you (claude) are the current speaker, compose your response and submit via `deliberation_respond` directly. Using `cli_auto_turn` would recursively spawn yourself and timeout.
198
+ 4. **NEVER re-ask after decline** — If user chooses "건너뛰기", respect it immediately. Do not ask again.
199
+ 5. **NEVER block on deliberation failure** — If MCP tools fail (server not running, speaker unavailable), warn the user and continue the original workflow. Deliberation is enhancement, not requirement.
200
+ 6. **NEVER modify existing superpowers skills** — This skill is purely additive. It works alongside existing skills without changing them.
201
+ 7. **NEVER omit verification source label** — 모든 검증 결과에 Gold/Silver 라벨을 반드시 표시. Self-criticism 결과를 Multi-AI 결과와 구분 없이 제시하면 신뢰도를 왜곡한다.
202
+
203
+ ## Workflow Position
204
+
205
+ ```
206
+ brainstorming ──────→ [deliberation-gate] → writing-plans → executing-plans
207
+ code-review ────────→ [deliberation-gate] → receiving-code-review
208
+ systematic-debugging → [deliberation-gate] → resume with consensus
209
+ explicit request ───→ [deliberation-gate] → context-dependent
210
+ ```
211
+
212
+ This skill is invoked BETWEEN existing superpowers skills, not within them. It consumes the output of one skill and feeds enhanced output to the next.