@heretek-ai/epistemic-swarm 0.2.3 → 0.3.0

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.
Files changed (138) hide show
  1. package/.agents/skills/brainstorming/SKILL.md +13 -0
  2. package/.agents/skills/code_audit/SKILL.md +13 -0
  3. package/.agents/skills/epistemic_search/SKILL.md +13 -0
  4. package/.agents/skills/grilling/SKILL.md +13 -0
  5. package/.agents/skills/oss_scout/SKILL.md +13 -0
  6. package/.agents/skills/research_cache/SKILL.md +13 -0
  7. package/.agents/skills/swarm_config/SKILL.md +13 -0
  8. package/.claude-plugin/plugin.json +15 -5
  9. package/.omp/README.md +39 -0
  10. package/.omp/SYSTEM.md +12 -0
  11. package/.omp/commands/audit.md +10 -0
  12. package/.omp/commands/brainstorming.md +12 -0
  13. package/.omp/commands/grill.md +9 -0
  14. package/.omp/commands/scout.md +10 -0
  15. package/.omp/commands/swarm-config.md +10 -0
  16. package/.omp/commands/swarm.md +9 -0
  17. package/.omp/hooks/post/epistemic-audit.ts +16 -0
  18. package/.omp/hooks/pre/epistemic-redirect.ts +21 -0
  19. package/.omp/prompts/brainstorming.md +8 -0
  20. package/.omp/prompts/swarm.md +8 -0
  21. package/MARKETPLACE.md +8 -0
  22. package/README.md +32 -3
  23. package/bin/cli.js +27 -3
  24. package/config/domain_packs/biopharma.json +23 -0
  25. package/config/domain_packs/legal.json +19 -0
  26. package/config/domain_packs/quant.json +19 -0
  27. package/config/mcp-research-servers.json +7 -0
  28. package/config/mcp_launcher.py +48 -137
  29. package/config/opencode-snippet.json +20 -1
  30. package/config/searxng_mcp.py +42 -83
  31. package/extensions/pi/index.js +138 -73
  32. package/install.sh +20 -4
  33. package/package.json +40 -5
  34. package/plugins/antigravity/README.md +28 -0
  35. package/plugins/antigravity/agents/alpha-thesis.md +6 -0
  36. package/plugins/antigravity/agents/beta-antithesis.md +7 -0
  37. package/plugins/antigravity/agents/brainstormer.md +7 -0
  38. package/plugins/antigravity/agents/epistemic-auditor.md +5 -0
  39. package/plugins/antigravity/hooks.json +23 -0
  40. package/plugins/antigravity/mcp_config.json +33 -0
  41. package/plugins/antigravity/plugin.json +21 -0
  42. package/plugins/antigravity/rules/epistemic-integrity.md +6 -0
  43. package/plugins/antigravity/skills/brainstorming/SKILL.md +13 -0
  44. package/plugins/antigravity/skills/code_audit/SKILL.md +13 -0
  45. package/plugins/antigravity/skills/epistemic_search/SKILL.md +13 -0
  46. package/plugins/antigravity/skills/grilling/SKILL.md +13 -0
  47. package/plugins/antigravity/skills/oss_scout/SKILL.md +13 -0
  48. package/plugins/antigravity/skills/research_cache/SKILL.md +13 -0
  49. package/plugins/antigravity/skills/swarm_config/SKILL.md +13 -0
  50. package/plugins/codex/AGENTS.md.snippet +10 -0
  51. package/plugins/codex/README.md +37 -0
  52. package/plugins/codex/config.toml.snippet +28 -0
  53. package/plugins/codex/openai.yaml +24 -0
  54. package/plugins/codex/skills/brainstorming/SKILL.md +13 -0
  55. package/plugins/codex/skills/code_audit/SKILL.md +13 -0
  56. package/plugins/codex/skills/epistemic_search/SKILL.md +13 -0
  57. package/plugins/codex/skills/grilling/SKILL.md +13 -0
  58. package/plugins/codex/skills/oss_scout/SKILL.md +13 -0
  59. package/plugins/codex/skills/research_cache/SKILL.md +13 -0
  60. package/plugins/codex/skills/swarm_config/SKILL.md +13 -0
  61. package/plugins/gemini/GEMINI.md +15 -0
  62. package/plugins/gemini/README.md +19 -0
  63. package/plugins/gemini/commands/audit.toml +6 -0
  64. package/plugins/gemini/commands/brainstorming.toml +10 -0
  65. package/plugins/gemini/commands/grill.toml +6 -0
  66. package/plugins/gemini/commands/scout.toml +7 -0
  67. package/plugins/gemini/commands/swarm-config.toml +7 -0
  68. package/plugins/gemini/commands/swarm.toml +8 -0
  69. package/plugins/gemini/gemini-extension.json +38 -0
  70. package/plugins/gemini/hooks/hooks.json +11 -0
  71. package/plugins/gemini/skills/brainstorming/SKILL.md +13 -0
  72. package/plugins/gemini/skills/code_audit/SKILL.md +13 -0
  73. package/plugins/gemini/skills/epistemic_search/SKILL.md +13 -0
  74. package/plugins/gemini/skills/grilling/SKILL.md +13 -0
  75. package/plugins/gemini/skills/oss_scout/SKILL.md +13 -0
  76. package/plugins/gemini/skills/research_cache/SKILL.md +13 -0
  77. package/plugins/gemini/skills/swarm_config/SKILL.md +13 -0
  78. package/plugins/opencode/index.js +326 -263
  79. package/prompts/agent_brainstormer.md +97 -0
  80. package/runner/__pycache__/__init__.cpython-311.pyc +0 -0
  81. package/runner/__pycache__/auctioneer.cpython-311.pyc +0 -0
  82. package/runner/__pycache__/auditor_engine.cpython-311.pyc +0 -0
  83. package/runner/__pycache__/claim_store.cpython-311.pyc +0 -0
  84. package/runner/__pycache__/claim_witness.cpython-311.pyc +0 -0
  85. package/runner/__pycache__/living_dossiers.cpython-311.pyc +0 -0
  86. package/runner/__pycache__/mcp_protocol.cpython-311.pyc +0 -0
  87. package/runner/__pycache__/mcp_server.cpython-311.pyc +0 -0
  88. package/runner/__pycache__/pcrb.cpython-311.pyc +0 -0
  89. package/runner/__pycache__/pcrb_verify.cpython-311.pyc +0 -0
  90. package/runner/__pycache__/refinement.cpython-311.pyc +0 -0
  91. package/runner/__pycache__/research_swarm.cpython-311.pyc +0 -0
  92. package/runner/__pycache__/state_machine.cpython-311.pyc +0 -0
  93. package/runner/auctioneer.py +169 -0
  94. package/runner/auditor_engine.py +127 -12
  95. package/runner/claim_store.py +361 -0
  96. package/runner/claim_witness.py +183 -0
  97. package/runner/living_dossiers.py +355 -0
  98. package/runner/mcp_protocol.py +188 -0
  99. package/runner/mcp_server.py +567 -0
  100. package/runner/pcrb.py +212 -0
  101. package/runner/pcrb_verify.py +237 -0
  102. package/runner/refinement.py +335 -0
  103. package/runner/research_swarm.py +378 -94
  104. package/runner/tests/__pycache__/test_auction_order.cpython-311.pyc +0 -0
  105. package/runner/tests/__pycache__/test_claim_store.cpython-311.pyc +0 -0
  106. package/runner/tests/__pycache__/test_claim_witness.cpython-311.pyc +0 -0
  107. package/runner/tests/__pycache__/test_domain_packs.cpython-311.pyc +0 -0
  108. package/runner/tests/__pycache__/test_fleet_seam.cpython-311.pyc +0 -0
  109. package/runner/tests/__pycache__/test_living_dossiers.cpython-311.pyc +0 -0
  110. package/runner/tests/__pycache__/test_mcp_server.cpython-311.pyc +0 -0
  111. package/runner/tests/__pycache__/test_pcrb.cpython-311.pyc +0 -0
  112. package/runner/tests/__pycache__/test_refinement.cpython-311.pyc +0 -0
  113. package/runner/tests/__pycache__/test_swarm.cpython-311.pyc +0 -0
  114. package/runner/tests/fixtures/auction_objective.json +35 -0
  115. package/runner/tests/fixtures/borderline_claims.json +27 -0
  116. package/runner/tests/fixtures/divergence_objectives.json +31 -0
  117. package/runner/tests/test_auction_order.py +173 -0
  118. package/runner/tests/test_claim_store.py +162 -0
  119. package/runner/tests/test_claim_witness.py +186 -0
  120. package/runner/tests/test_domain_packs.py +217 -0
  121. package/runner/tests/test_fleet_seam.py +113 -0
  122. package/runner/tests/test_living_dossiers.py +204 -0
  123. package/runner/tests/test_mcp_server.py +212 -0
  124. package/runner/tests/test_pcrb.py +240 -0
  125. package/runner/tests/test_refinement.py +255 -0
  126. package/runner/tests/test_swarm.py +137 -30
  127. package/scripts/auction_experiment.py +180 -0
  128. package/scripts/build_adapters.py +183 -0
  129. package/scripts/divergence_experiment.py +184 -0
  130. package/skills/brainstorming/SKILL.md +106 -0
  131. package/skills/brainstorming/__init__.py +1 -0
  132. package/skills/brainstorming/scripts/brainstorm.py +200 -0
  133. package/skills/research_cache/__pycache__/__init__.cpython-311.pyc +0 -0
  134. package/skills/research_cache/__pycache__/hasher.cpython-311.pyc +0 -0
  135. package/skills/swarm_config/SKILL.md +1 -1
  136. package/skills/swarm_config/__pycache__/__init__.cpython-311.pyc +0 -0
  137. package/skills/swarm_config/__pycache__/configure.cpython-311.pyc +0 -0
  138. package/skills/swarm_config/configure.py +45 -11
@@ -1,9 +1,14 @@
1
1
  /**
2
2
  * IUMBTEMS: I Use My Brain To Express My Self
3
3
  * Native Plugin for OpenCode V2 (opencode.ai)
4
- *
5
- * Exposes dialectic swarm research tools, codebase auditing, open-source scouting,
6
- * configuration management, and content-addressed quote verification directly into OpenCode V2 agents.
4
+ *
5
+ * THIN REGISTRATION (Stream A2b): this plugin no longer implements tools.
6
+ * Every tool forwards to the canonical first-party MCP surface:
7
+ *
8
+ * python3 runner/mcp_server.py call <tool> '<json>'
9
+ *
10
+ * The plugin exists only so OpenCode V2 hosts can discover the iumbtems_*
11
+ * catalog. Schemas mirror runner/mcp_server.py build_tools() — keep in sync.
7
12
  */
8
13
 
9
14
  import { spawnSync } from 'child_process';
@@ -13,289 +18,347 @@ import { fileURLToPath } from 'url';
13
18
  const __filename = fileURLToPath(import.meta.url);
14
19
  const __dirname = path.dirname(__filename);
15
20
  const PKG_ROOT = path.resolve(__dirname, '../..');
21
+ const MCP_SERVER = path.join(PKG_ROOT, 'runner', 'mcp_server.py');
16
22
 
17
- export function createOpenCodePlugin(context = {}) {
23
+ /** Uniform dispatch: one-shot MCP call, return OpenCode's {content, status}. */
24
+ function callMcp(tool, args = {}, cwd) {
25
+ const res = spawnSync(
26
+ 'python3',
27
+ [MCP_SERVER, 'call', tool, JSON.stringify(args || {})],
28
+ {
29
+ encoding: 'utf-8',
30
+ cwd: cwd || process.cwd(),
31
+ env: { ...process.env, PYTHONPATH: PKG_ROOT },
32
+ }
33
+ );
18
34
  return {
19
- id: "heretek.iumbtems.epistemic-swarm",
20
- name: "IUMBTEMS Epistemic Swarm",
21
- version: "0.2.3",
22
- description: "I Use My Brain To Express My Self: High-integrity dialectic research, code audits, and open-source scouting",
23
-
24
- server: (toolContext) => [
25
- {
26
- name: "iumbtems_config",
27
- description: "Inspect or modify the active Epistemic Swarm configuration (search engine, depth/iterations, operating mode, divergence threshold) in .research/config.json.",
28
- input: {
29
- type: "object",
30
- properties: {
31
- search_engine: {
32
- type: "string",
33
- enum: ["duckduckgo", "brave", "firecrawl", "searxng"],
34
- description: "Primary search engine (duckduckgo is the zero-key free default)"
35
- },
36
- max_iterations: {
37
- type: "integer",
38
- minimum: 1,
39
- maximum: 4,
40
- description: "Maximum dialectic research iterations / depth (1-4)"
41
- },
42
- mode: {
43
- type: "string",
44
- enum: ["research", "audit", "scout", "hybrid"],
45
- description: "Operating mode: research (literature), audit (codebase), scout (OSS), hybrid"
46
- },
47
- divergence_threshold: {
48
- type: "number",
49
- minimum: 0.0,
50
- maximum: 1.0,
51
- description: "Auditor divergence threshold (default 0.75)"
52
- },
53
- show: {
54
- type: "boolean",
55
- description: "Just inspect current configuration without modifying",
56
- default: false
57
- }
58
- }
59
- },
60
- options: { codemode: false },
61
- execute: async (args = {}) => {
62
- const configScript = path.join(PKG_ROOT, "skills/swarm_config/configure.py");
63
- const cmdArgs = [configScript];
35
+ content: res.stdout || res.stderr,
36
+ status: res.status === 0 ? 'success' : 'error',
37
+ };
38
+ }
64
39
 
65
- if (args.show || (!args.search_engine && !args.max_iterations && !args.mode && args.divergence_threshold === undefined)) {
66
- cmdArgs.push("--show");
67
- } else {
68
- if (args.search_engine) cmdArgs.push("--engine", args.search_engine);
69
- if (args.max_iterations) cmdArgs.push("--depth", String(args.max_iterations));
70
- if (args.mode) cmdArgs.push("--mode", args.mode);
71
- if (args.divergence_threshold !== undefined) cmdArgs.push("--divergence", String(args.divergence_threshold));
72
- }
40
+ /** Catalog mirrors runner/mcp_server.py build_tools(). */
41
+ export const IUMBTEMS_TOOL_NAMES = [
42
+ 'iumbtems_config',
43
+ 'iumbtems_swarm_research',
44
+ 'iumbtems_code_audit',
45
+ 'iumbtems_oss_scout',
46
+ 'iumbtems_brainstorm',
47
+ 'iumbtems_verify_quote',
48
+ 'iumbtems_socratic_frontier',
49
+ 'iumbtems_reindex_claims',
50
+ 'iumbtems_report_retraction',
51
+ 'iumbtems_check_staleness',
52
+ 'iumbtems_set_domain_pack',
53
+ 'iumbtems_export_brief',
54
+ 'iumbtems_verify_brief',
55
+ ];
73
56
 
74
- const res = spawnSync("python3", cmdArgs, {
75
- encoding: "utf-8",
76
- cwd: toolContext?.cwd || process.cwd(),
77
- env: { ...process.env, PYTHONPATH: PKG_ROOT }
78
- });
57
+ // Deprecated misspelled alias (pre-A2b export). Remove in a semver-major.
58
+ export const IUMBEMS_TOOL_NAMES = IUMBTEMS_TOOL_NAMES;
79
59
 
80
- return {
81
- content: res.stdout || res.stderr,
82
- status: res.status === 0 ? "success" : "error"
83
- };
84
- }
60
+ const TOOL_CATALOG = [
61
+ {
62
+ name: 'iumbtems_config',
63
+ description:
64
+ 'Inspect or modify the active Epistemic Swarm configuration (search engine, depth/iterations, operating mode, divergence threshold) in .research/config.json.',
65
+ input: {
66
+ type: 'object',
67
+ properties: {
68
+ search_engine: {
69
+ type: 'string',
70
+ enum: ['duckduckgo', 'brave', 'firecrawl', 'searxng'],
71
+ description: 'Primary search engine (duckduckgo is the zero-key free default)',
72
+ },
73
+ max_iterations: {
74
+ type: 'integer',
75
+ minimum: 1,
76
+ maximum: 4,
77
+ description: 'Maximum dialectic research iterations / depth (1-4)',
78
+ },
79
+ mode: {
80
+ type: 'string',
81
+ enum: ['research', 'audit', 'scout', 'hybrid', 'brainstorm'],
82
+ description: 'Operating mode: research (literature), audit (codebase), scout (OSS), hybrid, brainstorm (lateral ideation)',
83
+ },
84
+ divergence_threshold: {
85
+ type: 'number',
86
+ minimum: 0.0,
87
+ maximum: 1.0,
88
+ description: 'Auditor divergence threshold (default 0.75)',
89
+ },
90
+ show: {
91
+ type: 'boolean',
92
+ description: 'Just inspect current configuration without modifying',
93
+ default: false,
94
+ },
85
95
  },
86
-
87
- {
88
- name: "iumbtems_code_audit",
89
- description: "Run a dialectic codebase architectural and security audit pairing a structural architect with an adversarial red-teamer.",
90
- input: {
91
- type: "object",
92
- properties: {
93
- target: {
94
- type: "string",
95
- description: "Target directory, file, or architectural component to audit"
96
- },
97
- mock_mode: {
98
- type: "boolean",
99
- description: "Run in mock mode without invoking LLM tokens",
100
- default: false
101
- }
102
- },
103
- required: ["target"]
96
+ },
97
+ },
98
+ {
99
+ name: 'iumbtems_swarm_research',
100
+ description:
101
+ 'Execute an autonomous dialectic research swarm on an objective using Agent Alpha (Thesis) and Agent Beta (Red Team). Long-running; blocks until the swarm completes.',
102
+ input: {
103
+ type: 'object',
104
+ properties: {
105
+ objective: {
106
+ type: 'string',
107
+ description: 'The research question or hypothesis to investigate',
108
+ },
109
+ mock_mode: {
110
+ type: 'boolean',
111
+ description: 'Run in mock/dry-run mode without external API charges',
112
+ default: false,
104
113
  },
105
- options: { codemode: false },
106
- execute: async (args) => {
107
- const runnerPath = path.join(PKG_ROOT, "runner/research_swarm.py");
108
- const cmdArgs = [runnerPath, "--mode", "audit", "--objective", args.target];
109
- if (args.mock_mode) {
110
- cmdArgs.push("--mock-claude");
111
- }
112
-
113
- const res = spawnSync("python3", cmdArgs, {
114
- encoding: "utf-8",
115
- cwd: toolContext?.cwd || process.cwd(),
116
- env: { ...process.env, PYTHONPATH: PKG_ROOT }
117
- });
118
-
119
- return {
120
- content: res.stdout || res.stderr,
121
- status: res.status === 0 ? "success" : "error"
122
- };
123
- }
124
114
  },
125
-
126
- {
127
- name: "iumbtems_oss_scout",
128
- description: "Scout open-source software libraries, benchmark candidate implementations, red-team viral copyleft (GPL/AGPL), and produce clean-room implementation blueprints.",
129
- input: {
130
- type: "object",
131
- properties: {
132
- feature: {
133
- type: "string",
134
- description: "The feature, algorithm, or capability to scout in open source"
135
- },
136
- mock_mode: {
137
- type: "boolean",
138
- description: "Run in mock mode without invoking LLM tokens",
139
- default: false
140
- }
141
- },
142
- required: ["feature"]
115
+ required: ['objective'],
116
+ },
117
+ },
118
+ {
119
+ name: 'iumbtems_code_audit',
120
+ description:
121
+ 'Run a dialectic codebase architectural and security audit pairing a structural architect with an adversarial red-teamer.',
122
+ input: {
123
+ type: 'object',
124
+ properties: {
125
+ target: {
126
+ type: 'string',
127
+ description: 'Target directory, file, or architectural component to audit',
128
+ },
129
+ mock_mode: {
130
+ type: 'boolean',
131
+ description: 'Run in mock mode without invoking LLM tokens',
132
+ default: false,
143
133
  },
144
- options: { codemode: false },
145
- execute: async (args) => {
146
- const runnerPath = path.join(PKG_ROOT, "runner/research_swarm.py");
147
- const cmdArgs = [runnerPath, "--mode", "scout", "--objective", args.feature];
148
- if (args.mock_mode) {
149
- cmdArgs.push("--mock-claude");
150
- }
151
-
152
- const res = spawnSync("python3", cmdArgs, {
153
- encoding: "utf-8",
154
- cwd: toolContext?.cwd || process.cwd(),
155
- env: { ...process.env, PYTHONPATH: PKG_ROOT }
156
- });
157
-
158
- return {
159
- content: res.stdout || res.stderr,
160
- status: res.status === 0 ? "success" : "error"
161
- };
162
- }
163
134
  },
164
-
165
- {
166
- name: "iumbtems_swarm_research",
167
- description: "Execute an autonomous dialectic research swarm on an objective using Agent Alpha (Thesis) and Agent Beta (Red Team).",
168
- input: {
169
- type: "object",
170
- properties: {
171
- objective: {
172
- type: "string",
173
- description: "The research question or hypothesis to investigate"
174
- },
175
- mock_mode: {
176
- type: "boolean",
177
- description: "Run in mock/dry-run mode without external API charges",
178
- default: false
179
- }
180
- },
181
- required: ["objective"]
135
+ required: ['target'],
136
+ },
137
+ },
138
+ {
139
+ name: 'iumbtems_oss_scout',
140
+ description:
141
+ 'Scout open-source software libraries, benchmark candidate implementations, red-team viral copyleft (GPL/AGPL), and produce clean-room implementation blueprints.',
142
+ input: {
143
+ type: 'object',
144
+ properties: {
145
+ feature: {
146
+ type: 'string',
147
+ description: 'The feature, algorithm, or capability to scout in open source',
148
+ },
149
+ mock_mode: {
150
+ type: 'boolean',
151
+ description: 'Run in mock mode without invoking LLM tokens',
152
+ default: false,
182
153
  },
183
- options: { codemode: false },
184
- execute: async (args) => {
185
- const runnerPath = path.join(PKG_ROOT, "runner/research_swarm.py");
186
- const cmdArgs = [runnerPath, "--objective", args.objective];
187
- if (args.mock_mode) {
188
- cmdArgs.push("--mock-claude");
189
- }
190
-
191
- const res = spawnSync("python3", cmdArgs, {
192
- encoding: "utf-8",
193
- cwd: toolContext?.cwd || process.cwd(),
194
- env: { ...process.env, PYTHONPATH: PKG_ROOT }
195
- });
196
-
197
- return {
198
- content: res.stdout || res.stderr,
199
- status: res.status === 0 ? "success" : "error"
200
- };
201
- }
202
154
  },
203
-
204
- {
205
- name: "iumbtems_verify_quote",
206
- description: "Cryptographically verify whether a cited quote matches verbatim text inside the content-addressed source cache.",
207
- input: {
208
- type: "object",
209
- properties: {
210
- hash: {
211
- type: "string",
212
- description: "SHA-256 hash or prefix of the cached source"
213
- },
214
- quote: {
215
- type: "string",
216
- description: "The verbatim excerpt to verify"
217
- }
218
- },
219
- required: ["hash", "quote"]
155
+ required: ['feature'],
156
+ },
157
+ },
158
+ {
159
+ name: 'iumbtems_brainstorm',
160
+ description:
161
+ 'Run lateral brainstorming: novel feature vectors, paradigm inversions, and falsifiable spike hypotheses (never bug-fix lists).',
162
+ input: {
163
+ type: 'object',
164
+ properties: {
165
+ objective: {
166
+ type: 'string',
167
+ description: "Ambiguous exploration prompt (e.g. 'Where do we go from here?')",
168
+ },
169
+ mock_mode: {
170
+ type: 'boolean',
171
+ description: 'Run in mock/dry-run mode without external API charges',
172
+ default: false,
220
173
  },
221
- options: { codemode: false },
222
- execute: async (args) => {
223
- const hasherPath = path.join(PKG_ROOT, "skills/research-cache/hasher.py");
224
- const res = spawnSync("python3", [hasherPath, "verify", "--hash", args.hash, "--quote", args.quote], {
225
- encoding: "utf-8",
226
- cwd: toolContext?.cwd || process.cwd()
227
- });
228
-
229
- return {
230
- content: res.stdout || res.stderr,
231
- status: res.status === 0 ? "verified" : "failed"
232
- };
233
- }
234
174
  },
235
-
236
- {
237
- name: "iumbtems_socratic_frontier",
238
- description: "Inspect or advance the Socratic grilling decision frontier for research framing.",
239
- input: {
240
- type: "object",
241
- properties: {
242
- objective: {
243
- type: "string",
244
- description: "Research objective to inspect"
245
- },
246
- settle_node: {
247
- type: "string",
248
- description: "Optional node ID to settle with an answer"
249
- },
250
- settle_answer: {
251
- type: "string",
252
- description: "Answer for the settled node"
253
- }
254
- }
175
+ required: ['objective'],
176
+ },
177
+ },
178
+ {
179
+ name: 'iumbtems_verify_quote',
180
+ description:
181
+ 'Cryptographically verify whether a cited quote matches verbatim text inside the content-addressed source cache.',
182
+ input: {
183
+ type: 'object',
184
+ properties: {
185
+ hash: {
186
+ type: 'string',
187
+ description: 'SHA-256 hash or prefix of the cached source',
255
188
  },
256
- options: { codemode: false },
257
- execute: async (args) => {
258
- const treePath = path.join(PKG_ROOT, "skills/grilling/socratic_tree.py");
259
- const cmdArgs = [treePath];
189
+ quote: {
190
+ type: 'string',
191
+ description: 'The verbatim excerpt to verify',
192
+ },
193
+ },
194
+ required: ['hash', 'quote'],
195
+ },
196
+ },
197
+ {
198
+ name: 'iumbtems_socratic_frontier',
199
+ description: 'Inspect or advance the Socratic grilling decision frontier for research framing.',
200
+ input: {
201
+ type: 'object',
202
+ properties: {
203
+ objective: {
204
+ type: 'string',
205
+ description: 'Research objective to inspect',
206
+ },
207
+ settle_node: {
208
+ type: 'string',
209
+ description: 'Optional node ID to settle with an answer',
210
+ },
211
+ settle_answer: {
212
+ type: 'string',
213
+ description: 'Answer for the settled node',
214
+ },
215
+ },
216
+ },
217
+ },
218
+ {
219
+ name: 'iumbtems_reindex_claims',
220
+ description:
221
+ 'Rebuild the derived claims.sqlite index from .research flat files (idempotent; flat files are source of truth).',
222
+ input: {
223
+ type: 'object',
224
+ properties: {
225
+ base_dir: {
226
+ type: 'string',
227
+ description: 'Path to .research workspace',
228
+ },
229
+ },
230
+ },
231
+ },
232
+ {
233
+ name: 'iumbtems_report_retraction',
234
+ description:
235
+ 'Record a RETRACTED/REVISED event for a cached source; dependent VERIFIED claims degrade to STALE/SUSPECT on the next audit (Living Dossiers).',
236
+ input: {
237
+ type: 'object',
238
+ properties: {
239
+ hash: { type: 'string', description: 'Content-addressed SHA-256 of the affected source' },
240
+ event: { type: 'string', enum: ['RETRACTED', 'REVISED'] },
241
+ note: { type: 'string', description: 'Why the source was retracted/revised' },
242
+ base_dir: { type: 'string' },
243
+ },
244
+ required: ['hash', 'event'],
245
+ },
246
+ },
247
+ {
248
+ name: 'iumbtems_check_staleness',
249
+ description:
250
+ 'Run one claim-degradation pass: join claims against retraction events, write the status ledger, and queue re-runs for degraded scopes. Never mutates dossiers.',
251
+ input: {
252
+ type: 'object',
253
+ properties: {
254
+ base_dir: { type: 'string' },
255
+ scope_ids: {
256
+ type: 'array',
257
+ items: { type: 'string' },
258
+ description: 'Limit the pass to specific scopes',
259
+ },
260
+ },
261
+ },
262
+ },
263
+ {
264
+ name: 'iumbtems_set_domain_pack',
265
+ description:
266
+ 'Activate a Regulated Domain Pack (biopharma/quant/legal epistemic constitution) for subsequent audits.',
267
+ input: {
268
+ type: 'object',
269
+ properties: {
270
+ pack: { type: 'string', description: 'Pack id: biopharma | quant | legal (or a path)' },
271
+ base_dir: { type: 'string' },
272
+ },
273
+ required: ['pack'],
274
+ },
275
+ },
276
+ {
277
+ name: 'iumbtems_export_brief',
278
+ description:
279
+ 'Export a proof-carrying research brief (PCRB): self-contained signed bundle of synthesis, claims, quote witnesses, and full source texts.',
280
+ input: {
281
+ type: 'object',
282
+ properties: {
283
+ base_dir: { type: 'string' },
284
+ out: { type: 'string', description: 'Output path (default <base_dir>/brief.pcrb.json)' },
285
+ objective: { type: 'string' },
286
+ key: { type: 'string', description: 'HMAC key (prefer key_file or env IUMBTEMS_PCRB_KEY)' },
287
+ key_file: { type: 'string' },
288
+ },
289
+ },
290
+ },
291
+ {
292
+ name: 'iumbtems_verify_brief',
293
+ description:
294
+ 'Verify a proof-carrying brief against its BUNDLED sources: manifest integrity, HMAC signature, and every quote re-checked. Exit-fail semantics; no trust in the producing LLM.',
295
+ input: {
296
+ type: 'object',
297
+ properties: {
298
+ brief: { type: 'string', description: 'Path to brief.pcrb.json' },
299
+ key: { type: 'string' },
300
+ key_file: { type: 'string' },
301
+ },
302
+ required: ['brief'],
303
+ },
304
+ },
305
+ ];
260
306
 
261
- if (args.settle_node && args.settle_answer) {
262
- cmdArgs.push("--settle", args.settle_node, args.settle_answer);
263
- } else if (args.objective) {
264
- cmdArgs.push("--objective", args.objective, "--show-frontier");
265
- } else {
266
- cmdArgs.push("--show-frontier");
267
- }
307
+ /** Legacy arg shims -> MCP handler contract. */
308
+ function normalizeArgs(tool, args = {}) {
309
+ const a = { ...args };
310
+ if (a.mock_mode && a.mock_claude === undefined) {
311
+ a.mock_claude = a.mock_mode;
312
+ delete a.mock_mode;
313
+ }
314
+ if (a.show) {
315
+ delete a.show; // read-only inspect is the no-op default of iumbtems_config
316
+ }
317
+ if (tool === 'iumbtems_socratic_frontier') {
318
+ if (a.settle_node && a.settle_answer) {
319
+ a.settle = [a.settle_node, a.settle_answer];
320
+ delete a.settle_node;
321
+ delete a.settle_answer;
322
+ }
323
+ if (!a.file) {
324
+ a.file = '.research/frontier.json';
325
+ }
326
+ }
327
+ return a;
328
+ }
268
329
 
269
- const res = spawnSync("python3", cmdArgs, {
270
- encoding: "utf-8",
271
- cwd: toolContext?.cwd || process.cwd()
272
- });
330
+ export function createOpenCodePlugin(context = {}) {
331
+ return {
332
+ id: 'heretek.iumbtems.epistemic-swarm',
333
+ name: 'IUMBTEMS Epistemic Swarm',
334
+ version: '0.3.0',
335
+ description:
336
+ 'I Use My Brain To Express My Self: High-integrity dialectic research, code audits, and open-source scouting',
273
337
 
274
- return {
275
- content: res.stdout || res.stderr
276
- };
277
- }
278
- }
279
- ],
338
+ server: (toolContext) =>
339
+ TOOL_CATALOG.map((tool) => ({
340
+ ...tool,
341
+ options: { codemode: false },
342
+ execute: async (args = {}) =>
343
+ callMcp(tool.name, normalizeArgs(tool.name, args), toolContext?.cwd),
344
+ })),
280
345
 
281
346
  setup: async (appContext) => {
282
347
  const opts = context.options || appContext?.options;
283
- if (opts && typeof opts === "object") {
284
- const configScript = path.join(PKG_ROOT, "skills/swarm_config/configure.py");
285
- const cmdArgs = [configScript];
286
- if (opts.search_engine) cmdArgs.push("--engine", opts.search_engine);
287
- if (opts.max_iterations) cmdArgs.push("--depth", String(opts.max_iterations));
288
- if (opts.mode) cmdArgs.push("--mode", opts.mode);
289
- if (opts.divergence_threshold !== undefined) cmdArgs.push("--divergence", String(opts.divergence_threshold));
290
- if (cmdArgs.length > 1) {
291
- spawnSync("python3", cmdArgs, {
292
- cwd: appContext?.cwd || toolContext?.cwd || process.cwd(),
293
- env: { ...process.env, PYTHONPATH: PKG_ROOT }
294
- });
348
+ if (opts && typeof opts === 'object') {
349
+ const updates = {};
350
+ if (opts.search_engine) updates.search_engine = opts.search_engine;
351
+ if (opts.max_iterations) updates.max_iterations = opts.max_iterations;
352
+ if (opts.mode) updates.mode = opts.mode;
353
+ if (opts.divergence_threshold !== undefined) {
354
+ updates.divergence_threshold = opts.divergence_threshold;
355
+ }
356
+ if (Object.keys(updates).length > 0) {
357
+ callMcp('iumbtems_config', updates, appContext?.cwd);
295
358
  }
296
359
  }
297
- return { initialized: true, platform: "opencode-v2" };
298
- }
360
+ return { initialized: true, platform: 'opencode-v2' };
361
+ },
299
362
  };
300
363
  }
301
364