@dmsdc-ai/aigentry-deliberation 0.0.37 → 0.0.38

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
@@ -33,7 +33,7 @@ MCP Deliberation Server — Multi-session AI deliberation with smart speaker ord
33
33
  원클릭 설치 — 어떤 프로젝트 환경에서든 동작합니다:
34
34
 
35
35
  ```bash
36
- npx --yes --package @dmsdc-ai/aigentry-deliberation deliberation-install
36
+ npx @dmsdc-ai/aigentry-deliberation install
37
37
  ```
38
38
 
39
39
  이 명령은:
@@ -62,7 +62,7 @@ cd aigentry-deliberation && npm install && node install.js
62
62
  ### 제거
63
63
 
64
64
  ```bash
65
- npx --yes --package @dmsdc-ai/aigentry-deliberation deliberation-install --uninstall
65
+ npx @dmsdc-ai/aigentry-deliberation uninstall
66
66
  ```
67
67
 
68
68
  MCP 서버 등록 해제 + 설치 파일 삭제 + 스킬 파일 정리까지 자동 처리됩니다.
@@ -87,7 +87,7 @@ open demo/forum/index.html
87
87
  MCP 연결 문제 자동 진단:
88
88
 
89
89
  ```bash
90
- npx --yes --package @dmsdc-ai/aigentry-deliberation deliberation-doctor
90
+ npx @dmsdc-ai/aigentry-deliberation doctor
91
91
  ```
92
92
 
93
93
  Claude Code, Codex CLI, Gemini CLI의 MCP 설정을 자동 점검하고 문제를 진단합니다.
@@ -101,7 +101,6 @@ Claude Code, Codex CLI, Gemini CLI의 MCP 설정을 자동 점검하고 문제
101
101
  | `deliberation_synthesize` | Generate synthesis report |
102
102
  | `deliberation_status` | Check session status |
103
103
  | `deliberation_context` | Load project context |
104
- | `deliberation_inject_context` | Inject structured context or external experiment history into an active session |
105
104
  | `deliberation_history` | View discussion history |
106
105
  | `deliberation_list_active` | List active sessions |
107
106
  | `deliberation_list` | List archived sessions |
@@ -138,48 +137,6 @@ Telepty-managed sessions are now routed through the telepty bus instead of raw P
138
137
  - `session_health` bus events are cached for operator visibility
139
138
  - `deliberation_synthesize` validates and emits typed `deliberation_completed` envelopes for downstream automation
140
139
 
141
- ## Experiment Retrospectives
142
-
143
- For autoresearch-style keep/discard reviews, inject a compact experiment bundle after the session starts instead of bloating `topic`.
144
-
145
- Recommended rules:
146
- - keep the injected JSON around `1.5KB` to `2KB`
147
- - include only the last `3-5` relevant experiments
148
- - keep `key_changes` to at most `3` scalar before/after pairs
149
- - reference bulky artifacts (`results.tsv`, full `program.md`, JSONL logs) by path only
150
-
151
- Example:
152
-
153
- ```text
154
- deliberation_start(...)
155
- deliberation_inject_context(
156
- session_id: "experiment-review-123",
157
- speaker: "dustcraw",
158
- context: "{\"past_experiments\":[{\"experiment_id\":\"dg-20260310-001\",\"signal_kind\":\"INTEREST_DRIFT\",\"patch_summary\":\"Raised relevanceThreshold from 0.30 to 0.35\",\"patch_kind\":\"config\",\"key_changes\":{\"relevanceThreshold\":{\"before\":0.3,\"after\":0.35}},\"score\":0.08,\"score_label\":\"promotion_rate_delta\",\"metric_name\":\"promotion_rate_delta\",\"metric_delta\":0.08,\"verdict\":\"positive\",\"followup_action\":\"kept\",\"reasoning\":\"Threshold raise reduced noise; promotion quality improved 8%\"}],\"experiment_count\":1,\"success_rate\":1.0}"
159
- )
160
- ```
161
-
162
- If your synthesis needs an explicit experiment verdict, `structured` can now include `experiment_outcome`:
163
-
164
- ```json
165
- {
166
- "summary": "Lower the blast radius and re-run with stricter constraints.",
167
- "decisions": [
168
- "Keep the experiment loop bounded to one editable file",
169
- "Retry after restoring the failing test baseline"
170
- ],
171
- "actionable_tasks": [
172
- { "id": 1, "task": "Tighten editable globs", "project": "aigentry-devkit", "priority": "high" }
173
- ],
174
- "experiment_outcome": {
175
- "verdict": "modify",
176
- "suggested_action": "iterate",
177
- "confidence": 0.78,
178
- "measurement_window_hours": 24
179
- }
180
- }
181
- ```
182
-
183
140
  ## Speaker Ordering Strategies
184
141
 
185
142
  | Strategy | Description |
@@ -239,7 +196,7 @@ Inserts multi-AI verification gates at key [superpowers](https://github.com/obra
239
196
 
240
197
  **Fallback:** MCP 미설치 시 self-criticism 기반 자가 검증으로 대체 (Silver 등급). MCP 설치 시 멀티-AI 토론 (Gold 등급).
241
198
 
242
- **Install:** `npx --yes --package @dmsdc-ai/aigentry-deliberation deliberation-install` 실행 시 자동 설치됩니다.
199
+ **Install:** `npx @dmsdc-ai/aigentry-deliberation install` 실행 시 자동 설치됩니다.
243
200
 
244
201
  수동 설치:
245
202
  ```bash
package/doctor.js CHANGED
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * Usage:
17
17
  * node doctor.js
18
- * npx --yes --package @dmsdc-ai/aigentry-deliberation deliberation-doctor
18
+ * npx @dmsdc-ai/aigentry-deliberation doctor
19
19
  */
20
20
 
21
21
  import fs from "node:fs";
@@ -209,7 +209,7 @@ function suggestFix(serverName, server, issue) {
209
209
  switch (issue) {
210
210
  case "path_missing":
211
211
  if (serverName === "deliberation" || serverName === "mcp-deliberation") {
212
- return `npx --yes --package @dmsdc-ai/aigentry-deliberation deliberation-install`;
212
+ return `npx @dmsdc-ai/aigentry-deliberation install`;
213
213
  }
214
214
  if (serverName.includes("brain") || serverName.includes("aigentry-brain")) {
215
215
  return `npx @dmsdc-ai/aigentry-brain install`;
@@ -223,7 +223,7 @@ function suggestFix(serverName, server, issue) {
223
223
  case "temp_path": {
224
224
  const tempArg = (server.args || []).find((a) => isTempPath(a));
225
225
  if (serverName === "deliberation" || serverName === "mcp-deliberation") {
226
- return `npx --yes --package @dmsdc-ai/aigentry-deliberation deliberation-install # reinstall to permanent path`;
226
+ return `npx @dmsdc-ai/aigentry-deliberation install # reinstall to permanent path`;
227
227
  }
228
228
  if (serverName.includes("brain") || serverName.includes("aigentry-brain")) {
229
229
  return `npx @dmsdc-ai/aigentry-brain install # reinstall to permanent path`;
@@ -357,7 +357,7 @@ function runDiagnostics() {
357
357
  if (mod.includes("aigentry-brain") || mod.includes("brain")) {
358
358
  fix = `npx @dmsdc-ai/aigentry-brain install # temporary path → reinstall to permanent path`;
359
359
  } else if (mod.includes("deliberation") || mod.includes("mcp-deliberation")) {
360
- fix = `npx --yes --package @dmsdc-ai/aigentry-deliberation deliberation-install # temporary path -> reinstall to permanent path`;
360
+ fix = `npx @dmsdc-ai/aigentry-deliberation install # temporary path reinstall to permanent path`;
361
361
  } else {
362
362
  fix = `# temporary path (${mod}) — change to permanent path in MCP config`;
363
363
  }
@@ -387,7 +387,7 @@ function runDiagnostics() {
387
387
  } else {
388
388
  totalIssues++;
389
389
  console.log(` ❌ Server file not found: ${selfPath}`);
390
- console.log(` fix: npx --yes --package @dmsdc-ai/aigentry-deliberation deliberation-install`);
390
+ console.log(` fix: npx @dmsdc-ai/aigentry-deliberation install`);
391
391
  }
392
392
 
393
393
  // Check node_modules
@@ -407,7 +407,7 @@ function runDiagnostics() {
407
407
  } catch {
408
408
  totalIssues++;
409
409
  console.log(` ❌ Syntax error detected`);
410
- console.log(` fix: npx --yes --package @dmsdc-ai/aigentry-deliberation deliberation-install`);
410
+ console.log(` fix: npx @dmsdc-ai/aigentry-deliberation install`);
411
411
  }
412
412
 
413
413
  // ── Summary ──
package/index.js CHANGED
@@ -22,10 +22,9 @@ if (_cliArg === "--help" || _cliArg === "-h") {
22
22
  MCP Deliberation Server
23
23
 
24
24
  Usage:
25
- npx --yes --package @dmsdc-ai/aigentry-deliberation deliberation-install Install (preferred)
26
- npx --yes --package @dmsdc-ai/aigentry-deliberation deliberation-install --uninstall
25
+ npx @dmsdc-ai/aigentry-deliberation install Install (register MCP server)
26
+ npx @dmsdc-ai/aigentry-deliberation uninstall Uninstall
27
27
  npx @dmsdc-ai/aigentry-deliberation Run MCP server (stdio)
28
- npx --yes --package @dmsdc-ai/aigentry-deliberation deliberation-doctor Diagnose MCP wiring
29
28
 
30
29
  After installation, restart Claude Code to start using it.
31
30
  `);
@@ -144,32 +143,10 @@ const StructuredActionableTaskSchema = z.object({
144
143
  priority: z.enum(["high", "medium", "low"]).optional(),
145
144
  });
146
145
 
147
- const StructuredExperimentOutcomeSchema = z.object({
148
- verdict: z.enum(["keep", "discard", "modify"]),
149
- confidence: z.number().min(0).max(1).optional(),
150
- measurement_window_hours: z.number().nonnegative().optional(),
151
- patches: z.array(z.unknown()).optional(),
152
- suggested_action: z.enum(["advance", "revert", "iterate"]).optional(),
153
- });
154
-
155
146
  const StructuredSynthesisSchema = z.object({
156
147
  summary: z.string(),
157
148
  decisions: z.array(z.string()),
158
149
  actionable_tasks: z.array(StructuredActionableTaskSchema),
159
- experiment_outcome: StructuredExperimentOutcomeSchema.optional(),
160
- });
161
-
162
- const StructuredExecutionContractSchema = z.object({
163
- version: z.literal("v1"),
164
- source_session_id: z.string().min(1),
165
- summary: z.string(),
166
- tasks: z.array(StructuredActionableTaskSchema),
167
- experiment_outcome: StructuredExperimentOutcomeSchema.nullable().optional(),
168
- unresolved_questions: z.array(z.string()),
169
- artifact_refs: z.array(z.string()),
170
- generated_from: z.object({
171
- structured_synthesis_hash: z.string().length(40),
172
- }),
173
150
  });
174
151
 
175
152
  const TeleptyEnvelopeSchema = z.object({
@@ -202,7 +179,6 @@ const TeleptyDeliberationCompletedPayloadSchema = z.object({
202
179
  topic: z.string(),
203
180
  synthesis: z.string(),
204
181
  structured_synthesis: StructuredSynthesisSchema.nullable().optional(),
205
- execution_contract: StructuredExecutionContractSchema.nullable().optional(),
206
182
  });
207
183
 
208
184
  const TELEPTY_ENVELOPE_PAYLOAD_SCHEMAS = {
@@ -524,41 +500,6 @@ function hashPromptText(value) {
524
500
  return createHash("sha1").update(String(value || "")).digest("hex");
525
501
  }
526
502
 
527
- function sortJsonValue(value) {
528
- if (Array.isArray(value)) {
529
- return value.map(sortJsonValue);
530
- }
531
- if (value && typeof value === "object") {
532
- return Object.keys(value)
533
- .sort()
534
- .reduce((acc, key) => {
535
- acc[key] = sortJsonValue(value[key]);
536
- return acc;
537
- }, {});
538
- }
539
- return value;
540
- }
541
-
542
- function hashStructuredSynthesis(structured) {
543
- return hashPromptText(JSON.stringify(sortJsonValue(structured || null)));
544
- }
545
-
546
- function buildExecutionContract({ state, structured }) {
547
- if (!structured) return null;
548
- return {
549
- version: "v1",
550
- source_session_id: state.id,
551
- summary: structured.summary || "",
552
- tasks: structured.actionable_tasks || [],
553
- experiment_outcome: structured.experiment_outcome || null,
554
- unresolved_questions: [],
555
- artifact_refs: [],
556
- generated_from: {
557
- structured_synthesis_hash: hashStructuredSynthesis(structured),
558
- },
559
- };
560
- }
561
-
562
503
  function createEnvelopeId(prefix = "env") {
563
504
  return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
564
505
  }
@@ -619,11 +560,7 @@ function buildTeleptyTurnRequestEnvelope({ state, speaker, turnId, turnPrompt, i
619
560
  });
620
561
  }
621
562
 
622
- function buildTeleptySynthesisEnvelope({ state, synthesis, structured, executionContract }) {
623
- const derivedExecutionContract =
624
- executionContract !== undefined
625
- ? executionContract
626
- : (structured ? buildExecutionContract({ state, structured }) : (state.execution_contract || null));
563
+ function buildTeleptySynthesisEnvelope({ state, synthesis, structured }) {
627
564
  return buildTeleptyEnvelope({
628
565
  session_id: state.id,
629
566
  project: state.project || getProjectSlug(),
@@ -639,7 +576,6 @@ function buildTeleptySynthesisEnvelope({ state, synthesis, structured, execution
639
576
  topic: state.topic,
640
577
  synthesis,
641
578
  structured_synthesis: structured || null,
642
- execution_contract: derivedExecutionContract || null,
643
579
  },
644
580
  });
645
581
  }
@@ -2611,14 +2547,6 @@ tags: [deliberation]
2611
2547
  md += `## Synthesis\n\n${s.synthesis}\n\n---\n\n`;
2612
2548
  }
2613
2549
 
2614
- if (s.structured_synthesis) {
2615
- md += `## Structured Synthesis\n\n\`\`\`json\n${JSON.stringify(s.structured_synthesis, null, 2)}\n\`\`\`\n\n---\n\n`;
2616
- }
2617
-
2618
- if (s.execution_contract) {
2619
- md += `## Execution Contract\n\n\`\`\`json\n${JSON.stringify(s.execution_contract, null, 2)}\n\`\`\`\n\n---\n\n`;
2620
- }
2621
-
2622
2550
  md += `## Debate Log\n\n`;
2623
2551
  for (const entry of s.log) {
2624
2552
  md += `### ${entry.speaker} — Round ${entry.round}\n\n`;
@@ -4542,7 +4470,6 @@ async function runAutoHandoff(sessionId) {
4542
4470
  if (!loaded) return;
4543
4471
  loaded.synthesis = markdownSynthesis;
4544
4472
  loaded.structured_synthesis = structured;
4545
- loaded.execution_contract = buildExecutionContract({ state: loaded, structured });
4546
4473
  loaded.status = "completed";
4547
4474
  loaded.current_speaker = "none";
4548
4475
  saveSession(loaded);
@@ -5085,7 +5012,6 @@ server.tool(
5085
5012
 
5086
5013
  loaded.synthesis = synthesis;
5087
5014
  loaded.structured_synthesis = structured || null;
5088
- loaded.execution_contract = buildExecutionContract({ state: loaded, structured: structured || null });
5089
5015
  loaded.status = "completed";
5090
5016
  loaded.current_speaker = "none";
5091
5017
  saveSession(loaded);
@@ -5107,7 +5033,6 @@ server.tool(
5107
5033
  state,
5108
5034
  synthesis,
5109
5035
  structured,
5110
- executionContract: state.execution_contract || null,
5111
5036
  });
5112
5037
 
5113
5038
  // Immediately force-close monitor terminal (including physical Terminal) on deliberation end
package/install.js CHANGED
@@ -4,13 +4,13 @@
4
4
  * Deliberation MCP Server — One-click installer
5
5
  *
6
6
  * Usage:
7
- * npx --yes --package @dmsdc-ai/aigentry-deliberation deliberation-install
7
+ * npx @dmsdc-ai/aigentry-deliberation install
8
8
  * node install.js
9
9
  *
10
10
  * What it does:
11
11
  * 1. Copies server files to ~/.local/lib/mcp-deliberation/
12
12
  * 2. Installs npm dependencies
13
- * 3. Registers MCP server in ~/.claude/.mcp.json (Claude Code)
13
+ * 3. Registers MCP server via `claude mcp add` (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
16
  * 6. Installs skill file (~/.claude/skills/deliberation-gate/SKILL.md)
@@ -61,6 +61,15 @@ function log(msg) {
61
61
  console.log(` ${msg}`);
62
62
  }
63
63
 
64
+ function commandExists(cmd) {
65
+ try {
66
+ execSync(IS_WIN ? `where ${cmd}` : `command -v ${cmd}`, { stdio: "pipe" });
67
+ return true;
68
+ } catch {
69
+ return false;
70
+ }
71
+ }
72
+
64
73
  function copyFileIfExists(src, dest) {
65
74
  if (fs.existsSync(src)) {
66
75
  fs.copyFileSync(src, dest);
@@ -121,32 +130,55 @@ function install() {
121
130
  log(" Manual fix: cd ~/.local/lib/mcp-deliberation && npm install");
122
131
  }
123
132
 
124
- // Step 4: Register MCP server
133
+ // Step 4: Register MCP server (Claude Code)
125
134
  log("🔧 Registering Claude Code MCP server...");
126
- const claudeDir = path.join(HOME, ".claude");
127
- fs.mkdirSync(claudeDir, { recursive: true });
135
+ const serverEntryPoint = toForwardSlash(path.join(INSTALL_DIR, "index.js"));
136
+ let claudeRegistered = false;
128
137
 
129
- let mcpConfig = {};
130
- if (fs.existsSync(MCP_CONFIG)) {
138
+ // Prefer `claude mcp add` — this is the only method Claude Code reliably reads
139
+ if (commandExists("claude")) {
131
140
  try {
132
- mcpConfig = JSON.parse(fs.readFileSync(MCP_CONFIG, "utf-8"));
133
- } catch {
134
- mcpConfig = {};
141
+ // Remove existing registration first (ignore errors if not registered)
142
+ try { execSync("claude mcp remove deliberation -s user", { stdio: "pipe" }); } catch { /* ok */ }
143
+ execSync(`claude mcp add deliberation -s user -- node "${serverEntryPoint}"`, {
144
+ stdio: "pipe",
145
+ });
146
+ log(" → Registered via 'claude mcp add' (user scope)");
147
+ claudeRegistered = true;
148
+ } catch (err) {
149
+ log(` ⚠️ 'claude mcp add' failed: ${err.message}`);
135
150
  }
136
151
  }
137
152
 
138
- if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
153
+ // Fallback: write ~/.claude/.mcp.json (legacy, may not be read by Claude Code)
154
+ if (!claudeRegistered) {
155
+ const claudeDir = path.join(HOME, ".claude");
156
+ fs.mkdirSync(claudeDir, { recursive: true });
139
157
 
140
- const alreadyRegistered = !!mcpConfig.mcpServers.deliberation;
141
- mcpConfig.mcpServers.deliberation = {
142
- command: "node",
143
- args: [toForwardSlash(path.join(INSTALL_DIR, "index.js"))],
144
- };
158
+ let mcpConfig = {};
159
+ if (fs.existsSync(MCP_CONFIG)) {
160
+ try {
161
+ mcpConfig = JSON.parse(fs.readFileSync(MCP_CONFIG, "utf-8"));
162
+ } catch {
163
+ mcpConfig = {};
164
+ }
165
+ }
166
+
167
+ if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
168
+
169
+ const alreadyRegistered = !!mcpConfig.mcpServers.deliberation;
170
+ mcpConfig.mcpServers.deliberation = {
171
+ command: "node",
172
+ args: [serverEntryPoint],
173
+ };
145
174
 
146
- fs.writeFileSync(MCP_CONFIG, JSON.stringify(mcpConfig, null, 2));
147
- log(alreadyRegistered
148
- ? " → Existing registration updated"
149
- : " → Registered successfully");
175
+ fs.writeFileSync(MCP_CONFIG, JSON.stringify(mcpConfig, null, 2));
176
+ log(alreadyRegistered
177
+ ? " → Fallback: existing registration updated in .mcp.json"
178
+ : " → Fallback: registered in .mcp.json");
179
+ log(" ⚠️ Claude CLI not found. Run manually if server isn't detected:");
180
+ log(` claude mcp add deliberation -s user -- node "${serverEntryPoint}"`);
181
+ }
150
182
 
151
183
  // Step 5: Register Gemini CLI MCP server
152
184
  log("🔧 Registering Gemini CLI MCP server...");
@@ -261,7 +293,7 @@ if (args.includes("--help") || args.includes("-h")) {
261
293
  Deliberation MCP Server Installer
262
294
 
263
295
  Usage:
264
- npx --yes --package @dmsdc-ai/aigentry-deliberation deliberation-install
296
+ npx @dmsdc-ai/aigentry-deliberation install
265
297
  node install.js
266
298
 
267
299
  Options:
@@ -283,14 +315,24 @@ Skill path: ${SKILL_DEST}
283
315
  } else if (args.includes("--uninstall") || args.includes("uninstall")) {
284
316
  console.log("\n🗑️ Deliberation MCP Server — Uninstalling\n");
285
317
 
286
- // Remove from Claude MCP config
318
+ // Remove from Claude Code MCP registration
319
+ let claudeUnregistered = false;
320
+ if (commandExists("claude")) {
321
+ try {
322
+ execSync("claude mcp remove deliberation -s user", { stdio: "pipe" });
323
+ log("Claude Code MCP server unregistered via 'claude mcp remove'");
324
+ claudeUnregistered = true;
325
+ } catch { /* may not exist */ }
326
+ }
327
+
328
+ // Also clean up legacy .mcp.json fallback
287
329
  if (fs.existsSync(MCP_CONFIG)) {
288
330
  try {
289
331
  const mcpConfig = JSON.parse(fs.readFileSync(MCP_CONFIG, "utf-8"));
290
332
  if (mcpConfig.mcpServers?.deliberation) {
291
333
  delete mcpConfig.mcpServers.deliberation;
292
334
  fs.writeFileSync(MCP_CONFIG, JSON.stringify(mcpConfig, null, 2));
293
- log("Claude Code MCP server unregistered");
335
+ if (!claudeUnregistered) log("Claude Code MCP server unregistered from .mcp.json");
294
336
  }
295
337
  } catch { /* ignore */ }
296
338
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dmsdc-ai/aigentry-deliberation",
3
- "version": "0.0.37",
3
+ "version": "0.0.38",
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",
@@ -27,7 +27,6 @@ Claude/Codex를 포함해 MCP를 지원하는 임의 CLI들이 구조화된 토
27
27
  | `deliberation_speaker_candidates` | 참가 가능한 speaker 후보 목록 조회 | 불필요 |
28
28
  | `deliberation_list_active` | 진행 중인 모든 세션 목록 | 불필요 |
29
29
  | `deliberation_status` | 토론 상태 조회 | 선택적* |
30
- | `deliberation_inject_context` | 외부 실험 결과/추가 컨텍스트 주입 | 선택적 |
31
30
  | `deliberation_context` | 프로젝트 컨텍스트 로드 | 불필요 |
32
31
  | `deliberation_browser_llm_tabs` | 브라우저 LLM 탭 목록 (웹 기반 LLM 참여용) | 불필요 |
33
32
  | `deliberation_route_turn` | 현재 차례 speaker의 transport(CLI/browser_auto/manual)를 자동 라우팅 | 선택적* |
@@ -107,57 +106,7 @@ Claude/Codex를 포함해 MCP를 지원하는 임의 CLI들이 구조화된 토
107
106
  4. 각 세션을 `session_id`로 명시해 독립 진행
108
107
  5. 각각 `deliberation_synthesize`로 개별 종료
109
108
 
110
- ### C. 실험 회고 / keep-discard review
111
- autoresearch 스타일 실험 루프를 검토할 때는 긴 컨텍스트를 `topic`에 섞지 말고, 시작 후 `deliberation_inject_context`로 compact bundle을 넣습니다.
112
-
113
- 권장 규칙:
114
- - inject payload는 `1.5KB ~ 2KB` 목표
115
- - 최근 `3~5`개 실험만 포함
116
- - `key_changes`는 최대 `3`개 scalar before/after만 유지
117
- - 전체 `results.tsv` / 전체 `program.md`는 넣지 말고 artifact path만 남김
118
-
119
- 예:
120
- ```text
121
- 1. deliberation_start(topic: "experiment retrospective / keep-discard review", ...)
122
- 2. deliberation_inject_context(
123
- session_id: "<session_id>",
124
- speaker: "dustcraw",
125
- context: JSON.stringify({
126
- past_experiments: [{
127
- experiment_id: "dg-20260310-001",
128
- signal_kind: "INTEREST_DRIFT",
129
- patch_summary: "Raised relevanceThreshold from 0.30 to 0.35",
130
- patch_kind: "config",
131
- key_changes: {
132
- relevanceThreshold: { before: 0.30, after: 0.35 }
133
- },
134
- score: 0.08,
135
- score_label: "promotion_rate_delta",
136
- metric_name: "promotion_rate_delta",
137
- metric_delta: 0.08,
138
- verdict: "positive",
139
- followup_action: "kept",
140
- reasoning: "Threshold raise reduced noise; promotion quality improved 8%"
141
- }],
142
- experiment_count: 1,
143
- success_rate: 1.0
144
- })
145
- )
146
- 3. deliberation_route_turn(...) 반복
147
- 4. deliberation_synthesize(..., structured: {
148
- summary: "...",
149
- decisions: ["..."],
150
- actionable_tasks: [...],
151
- experiment_outcome: {
152
- verdict: "modify",
153
- suggested_action: "iterate",
154
- confidence: 0.78,
155
- measurement_window_hours: 24
156
- }
157
- })
158
- ```
159
-
160
- ### D. 자동 진행 (스크립트)
109
+ ### C. 자동 진행 (스크립트)
161
110
  ```bash
162
111
  # 새 토론
163
112
  bash auto-deliberate.sh "저장소 전략"
@@ -169,7 +118,7 @@ bash auto-deliberate.sh "API 설계" 5
169
118
  bash auto-deliberate.sh --resume <session_id>
170
119
  ```
171
120
 
172
- ### E. 모니터링
121
+ ### D. 모니터링
173
122
  ```bash
174
123
  # 모든 활성 세션 모니터링
175
124
  bash deliberation-monitor.sh
@@ -181,14 +130,14 @@ bash deliberation-monitor.sh <session_id>
181
130
  bash deliberation-monitor.sh --tmux
182
131
  ```
183
132
 
184
- ### F. 브라우저 LLM 자동 연결 (CDP Auto-Activation)
133
+ ### E. 브라우저 LLM 자동 연결 (CDP Auto-Activation)
185
134
  - 브라우저 LLM speaker가 선택되면 CDP(Chrome DevTools Protocol)가 자동으로 활성화됩니다.
186
135
  - macOS에서는 Chrome이 실행되지 않은 경우 `--remote-debugging-port=9222`로 자동 실행을 시도합니다.
187
136
  - **Chrome이 이미 CDP 없이 실행 중인 경우**: Chrome을 완전히 종료한 후 다시 시도해야 합니다. (최초 1회만 필요)
188
137
  - CDP 연결 성공 시 모든 브라우저 speaker는 ⚡자동 모드로 동작합니다.
189
138
  - Windows/Linux에서는 사용자가 직접 Chrome을 `--remote-debugging-port=9222`로 실행해야 합니다.
190
139
 
191
- ### G. Chrome 확장 프로그램 사이드패널 지원
140
+ ### F. Chrome 확장 프로그램 사이드패널 지원
192
141
  - **Chrome 확장 프로그램 사이드패널 (chrome-extension:// URL)은 지원됩니다.**
193
142
  - Claude, ChatGPT, Gemini 등의 Chrome 확장 사이드패널도 CDP를 통해 deliberation 참가자로 사용 가능합니다.
194
143
  - 사이드패널은 title 기반 매칭으로 감지됩니다 (extension ID가 아닌 탭 제목으로 식별).