@heretek-ai/epistemic-swarm 0.2.0 → 0.2.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/.claude-plugin/marketplace.json +36 -9
- package/.claude-plugin/plugin.json +47 -41
- package/MARKETPLACE.md +93 -0
- package/README.md +39 -2
- package/bin/cli.js +58 -0
- package/config/mcp_launcher.py +215 -0
- package/hooks/hooks.json +24 -0
- package/package.json +26 -3
- package/plugins/research-cache/.claude-plugin/plugin.json +15 -0
- package/plugins/socratic-grilling/.claude-plugin/plugin.json +15 -0
- package/plugins/socratic-grilling/skills/grilling/SKILL.md +48 -0
- package/plugins/socratic-grilling/skills/grilling/__init__.py +0 -0
- package/plugins/socratic-grilling/skills/grilling/socratic_tree.py +148 -0
- package/prompts/agent_code_auditor.md +88 -0
- package/prompts/agent_oss_scout.md +78 -0
- package/runner/__pycache__/__init__.cpython-311.pyc +0 -0
- package/runner/__pycache__/auditor_engine.cpython-311.pyc +0 -0
- package/runner/__pycache__/research_swarm.cpython-311.pyc +0 -0
- package/runner/__pycache__/state_machine.cpython-311.pyc +0 -0
- package/runner/research_swarm.py +230 -81
- package/runner/tests/__pycache__/test_swarm.cpython-311.pyc +0 -0
- package/runner/tests/test_swarm.py +37 -0
- package/skills/code_audit/SKILL.md +45 -0
- package/skills/epistemic_search/SKILL.md +35 -0
- package/skills/epistemic_search/__init__.py +1 -0
- package/skills/epistemic_search/scripts/fetch.py +157 -0
- package/skills/epistemic_search/scripts/search.py +162 -0
- package/skills/oss_scout/SKILL.md +49 -0
- package/skills/research_cache/SKILL.md +36 -0
- package/skills/research_cache/__init__.py +0 -0
- package/skills/research_cache/__pycache__/__init__.cpython-311.pyc +0 -0
- package/skills/{research-cache → research_cache}/__pycache__/hasher.cpython-311.pyc +0 -0
- package/skills/research_cache/hasher.py +195 -0
- package/skills/swarm_config/SKILL.md +72 -0
- package/skills/swarm_config/__init__.py +4 -0
- package/skills/swarm_config/__pycache__/__init__.cpython-311.pyc +0 -0
- package/skills/swarm_config/__pycache__/configure.cpython-311.pyc +0 -0
- package/skills/swarm_config/configure.py +167 -0
- package/skills/research-cache/__pycache__/__init__.cpython-311.pyc +0 -0
- /package/{skills/research-cache → plugins/research-cache/skills/research_cache}/SKILL.md +0 -0
- /package/{skills/research-cache → plugins/research-cache/skills/research_cache}/__init__.py +0 -0
- /package/{skills/research-cache → plugins/research-cache/skills/research_cache}/hasher.py +0 -0
package/runner/research_swarm.py
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Epistemic Swarm: Dialectic Multi-Agent Research Runner.
|
|
4
4
|
Executes parallel Claude Code sub-processes (claude -p) for Proponent and Adversary agents,
|
|
5
5
|
monitors filesystem IPC scratchpads, and invokes the Epistemic Auditor.
|
|
6
|
+
Supports multiple modes: research, audit (codebase), scout (OSS), and hybrid.
|
|
6
7
|
"""
|
|
7
8
|
|
|
8
9
|
import os
|
|
@@ -23,11 +24,18 @@ sys.path.insert(0, str(PROJECT_ROOT))
|
|
|
23
24
|
from runner.state_machine import ResearchStateMachine, SessionStatus, ScopeStatus
|
|
24
25
|
from runner.auditor_engine import EpistemicAuditorEngine
|
|
25
26
|
from skills.research_cache.hasher import SourceHasher
|
|
27
|
+
from skills.swarm_config.configure import load_config
|
|
26
28
|
|
|
27
29
|
class SwarmRunner:
|
|
28
|
-
def __init__(self, base_dir: Optional[Path] = None, mock_mode: bool = False
|
|
30
|
+
def __init__(self, base_dir: Optional[Path] = None, mock_mode: bool = False,
|
|
31
|
+
mode: Optional[str] = None, engine: Optional[str] = None,
|
|
32
|
+
depth: Optional[int] = None):
|
|
29
33
|
self.base_dir = base_dir or Path(".research")
|
|
30
34
|
self.mock_mode = mock_mode
|
|
35
|
+
self.config = load_config(str(self.base_dir))
|
|
36
|
+
self.mode = mode or self.config.get("mode", "research")
|
|
37
|
+
self.engine = engine or self.config.get("search_engine", "duckduckgo")
|
|
38
|
+
self.depth = depth or self.config.get("max_iterations", 2)
|
|
31
39
|
self.state_machine = ResearchStateMachine(base_dir=self.base_dir)
|
|
32
40
|
self.auditor = EpistemicAuditorEngine(base_dir=self.base_dir)
|
|
33
41
|
self.hasher = SourceHasher(base_dir=self.base_dir)
|
|
@@ -76,8 +84,8 @@ class SwarmRunner:
|
|
|
76
84
|
return "MOCK_RESPONSE"
|
|
77
85
|
|
|
78
86
|
def orchestrate_objective(self, objective: str, frontier_file: Optional[Path] = None) -> List[Dict[str, Any]]:
|
|
79
|
-
"""Phase 1: Run Swarm Orchestrator to decompose the research question."""
|
|
80
|
-
print(f"\n🧠 [Phase 1: Orchestration] Decomposing objective: '{objective}'...")
|
|
87
|
+
"""Phase 1: Run Swarm Orchestrator to decompose the research/audit question."""
|
|
88
|
+
print(f"\n🧠 [Phase 1: Orchestration] Decomposing objective ({self.mode.upper()} mode): '{objective}'...")
|
|
81
89
|
self.state_machine.init_session(objective)
|
|
82
90
|
self.state_machine.update_session_status(SessionStatus.ORCHESTRATING)
|
|
83
91
|
|
|
@@ -88,8 +96,10 @@ class SwarmRunner:
|
|
|
88
96
|
frontier_context = f"\nSETTLED CONSTRAINTS FROM FRONTIER:\n{json.dumps(frontier_data.get('settled_constraints', {}), indent=2)}"
|
|
89
97
|
|
|
90
98
|
orchestrator_prompt = f"""
|
|
91
|
-
You are the Swarm Orchestrator. Read prompts/orchestrator.md.
|
|
99
|
+
You are the Swarm Orchestrator operating in {self.mode.upper()} mode. Read prompts/orchestrator.md.
|
|
92
100
|
Objective: {objective}
|
|
101
|
+
Engine: {self.engine}
|
|
102
|
+
Max Depth: {self.depth}
|
|
93
103
|
{frontier_context}
|
|
94
104
|
|
|
95
105
|
Output ONLY valid JSON representing the scope decomposition conforming to prompts/orchestrator.md.
|
|
@@ -125,45 +135,90 @@ Output ONLY valid JSON representing the scope decomposition conforming to prompt
|
|
|
125
135
|
return scopes
|
|
126
136
|
|
|
127
137
|
def run_agent_alpha(self, scope: Dict[str, Any]):
|
|
128
|
-
"""Executes Agent Alpha (Thesis / Proponent) for a scope."""
|
|
138
|
+
"""Executes Agent Alpha (Thesis / Proponent / Structural Auditor) for a scope."""
|
|
129
139
|
scope_id = scope["scope_id"]
|
|
130
|
-
print(f" [Alpha] 🏛️ Starting Agent Alpha (Thesis) on [{scope_id}]...")
|
|
140
|
+
print(f" [Alpha] 🏛️ Starting Agent Alpha ({self.mode.upper()} Thesis) on [{scope_id}]...")
|
|
131
141
|
|
|
132
142
|
if self.mock_mode:
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
143
|
+
if self.mode == "audit":
|
|
144
|
+
sample_content = "# System State Machine Architecture\nAtomic state transitions enforce ACID consistency via write-then-rename."
|
|
145
|
+
shash = self.hasher.store_source("file:///runner/state_machine.py", sample_content, "State Machine")
|
|
146
|
+
dossier = {
|
|
147
|
+
"agent": "Agent Alpha (Code Architect)",
|
|
148
|
+
"mode": "code_audit",
|
|
149
|
+
"scope_id": scope_id,
|
|
150
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
151
|
+
"affirmative_claims": [
|
|
152
|
+
{
|
|
153
|
+
"claim_id": "ALPHA-A01",
|
|
154
|
+
"tag": "VERIFIED",
|
|
155
|
+
"statement": "State machine transitions enforce atomic ACID guarantees across scratchpad files.",
|
|
156
|
+
"source_hash": shash,
|
|
157
|
+
"source_url": "file:///runner/state_machine.py#L45-L65",
|
|
158
|
+
"verbatim_quote": "Atomic state transitions enforce ACID consistency via write-then-rename."
|
|
159
|
+
}
|
|
160
|
+
],
|
|
161
|
+
"inferred_implications": [],
|
|
162
|
+
"negative_knowledge": []
|
|
163
|
+
}
|
|
164
|
+
elif self.mode == "scout":
|
|
165
|
+
sample_content = "# High Performance Raft in Rust\nZero-dependency Raft implementation with 150k ops/sec throughput under Apache-2.0."
|
|
166
|
+
shash = self.hasher.store_source("https://github.com/example/rust-raft", sample_content, "Rust Raft")
|
|
167
|
+
dossier = {
|
|
168
|
+
"agent": "Agent Alpha (OSS Scout)",
|
|
169
|
+
"mode": "oss_scout",
|
|
170
|
+
"scope_id": scope_id,
|
|
171
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
172
|
+
"affirmative_claims": [
|
|
173
|
+
{
|
|
174
|
+
"claim_id": "ALPHA-S01",
|
|
175
|
+
"tag": "VERIFIED",
|
|
176
|
+
"statement": "Rust-Raft achieves 150k ops/sec with zero external dependencies.",
|
|
177
|
+
"source_hash": shash,
|
|
178
|
+
"source_url": "https://github.com/example/rust-raft",
|
|
179
|
+
"verbatim_quote": "Zero-dependency Raft implementation with 150k ops/sec throughput under Apache-2.0."
|
|
180
|
+
}
|
|
181
|
+
],
|
|
182
|
+
"inferred_implications": [],
|
|
183
|
+
"negative_knowledge": []
|
|
184
|
+
}
|
|
185
|
+
else:
|
|
186
|
+
sample_content = "# FPGA Prover Benchmark\nOur FPGA pipeline executes the Poseidon round constraints in 184ms with a peak memory bandwidth of 45 GB/s."
|
|
187
|
+
shash = self.hasher.store_source("https://arxiv.org/abs/2405.0001", sample_content, "FPGA Benchmark")
|
|
188
|
+
dossier = {
|
|
189
|
+
"agent": "Agent Alpha (Thesis)",
|
|
190
|
+
"scope_id": scope_id,
|
|
191
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
192
|
+
"affirmative_claims": [
|
|
193
|
+
{
|
|
194
|
+
"claim_id": "ALPHA-C01",
|
|
195
|
+
"tag": "VERIFIED",
|
|
196
|
+
"statement": "FPGA-accelerated Poseidon provers achieve sub-200ms latency on 2^20 constraints.",
|
|
197
|
+
"source_hash": shash,
|
|
198
|
+
"source_url": "https://arxiv.org/abs/2405.0001",
|
|
199
|
+
"verbatim_quote": "Our FPGA pipeline executes the Poseidon round constraints in 184ms with a peak memory bandwidth of 45 GB/s."
|
|
200
|
+
}
|
|
201
|
+
],
|
|
202
|
+
"inferred_implications": [
|
|
203
|
+
{
|
|
204
|
+
"inference_id": "ALPHA-I01",
|
|
205
|
+
"tag": "INFERRED",
|
|
206
|
+
"statement": "Hardware provers satisfy 1-second block finality bounds.",
|
|
207
|
+
"parent_claims": ["ALPHA-C01"],
|
|
208
|
+
"deductive_logic": "184ms << 1000ms target."
|
|
209
|
+
}
|
|
210
|
+
],
|
|
211
|
+
"negative_knowledge": []
|
|
212
|
+
}
|
|
162
213
|
else:
|
|
163
|
-
prompt = f"Run Agent Alpha for scope: {json.dumps(scope)}. Save findings to {scope_id} scratchpad."
|
|
164
|
-
|
|
214
|
+
prompt = f"Run Agent Alpha ({self.mode} mode) for scope: {json.dumps(scope)}. Engine: {self.engine}. Depth: {self.depth}. Save findings to {scope_id} scratchpad."
|
|
215
|
+
if self.mode == "audit":
|
|
216
|
+
system_prompt = self.prompts_dir / "agent_code_auditor.md"
|
|
217
|
+
elif self.mode == "scout":
|
|
218
|
+
system_prompt = self.prompts_dir / "agent_oss_scout.md"
|
|
219
|
+
else:
|
|
220
|
+
system_prompt = self.prompts_dir / "agent_alpha_thesis.md"
|
|
165
221
|
self.run_claude_process(prompt, system_prompt_file=system_prompt)
|
|
166
|
-
# Read created dossier from scratchpad
|
|
167
222
|
dossier_path = self.state_machine.get_scope_dir(scope_id) / "alpha_dossier.json"
|
|
168
223
|
with open(dossier_path, "r", encoding="utf-8") as f:
|
|
169
224
|
dossier = json.load(f)
|
|
@@ -174,43 +229,105 @@ Output ONLY valid JSON representing the scope decomposition conforming to prompt
|
|
|
174
229
|
def run_agent_beta(self, scope: Dict[str, Any]):
|
|
175
230
|
"""Executes Agent Beta (Antithesis / Red Team) for a scope."""
|
|
176
231
|
scope_id = scope["scope_id"]
|
|
177
|
-
print(f" [Beta] 🎯 Starting Agent Beta (Red Team) on [{scope_id}]...")
|
|
232
|
+
print(f" [Beta] 🎯 Starting Agent Beta ({self.mode.upper()} Red Team) on [{scope_id}]...")
|
|
178
233
|
|
|
179
234
|
if self.mock_mode:
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
235
|
+
if self.mode == "audit":
|
|
236
|
+
sample_content = "# Concurrency Analysis\nSubprocess writes may conflict if file descriptors are left open across parallel threads."
|
|
237
|
+
shash = self.hasher.store_source("file:///runner/state_machine.py#race", sample_content, "Concurrency Check")
|
|
238
|
+
dossier = {
|
|
239
|
+
"agent": "Agent Beta (Code Red Team)",
|
|
240
|
+
"mode": "code_audit",
|
|
241
|
+
"scope_id": scope_id,
|
|
242
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
243
|
+
"falsification_claims": [
|
|
244
|
+
{
|
|
245
|
+
"claim_id": "BETA-A01",
|
|
246
|
+
"tag": "VERIFIED",
|
|
247
|
+
"statement": "Subprocess writes may conflict if file descriptors are left open across parallel threads.",
|
|
248
|
+
"source_hash": shash,
|
|
249
|
+
"source_url": "file:///runner/state_machine.py#race",
|
|
250
|
+
"verbatim_quote": "Subprocess writes may conflict if file descriptors are left open across parallel threads.",
|
|
251
|
+
"severity": "MEDIUM"
|
|
252
|
+
}
|
|
253
|
+
],
|
|
254
|
+
"methodological_critiques": [
|
|
255
|
+
{
|
|
256
|
+
"target_assertion": "State machine transitions enforce atomic ACID guarantees across scratchpad files.",
|
|
257
|
+
"critique": "Unprotected open(..., 'w') creates race condition window between concurrent agents.",
|
|
258
|
+
"evidence_hash": shash
|
|
259
|
+
}
|
|
260
|
+
],
|
|
261
|
+
"negative_knowledge": []
|
|
262
|
+
}
|
|
263
|
+
elif self.mode == "scout":
|
|
264
|
+
sample_content = "# High Performance Raft in Rust\nZero-dependency Raft implementation with 150k ops/sec throughput under Apache-2.0."
|
|
265
|
+
shash = self.hasher.store_source("https://github.com/example/rust-raft", sample_content, "Rust Raft")
|
|
266
|
+
dossier = {
|
|
267
|
+
"agent": "Agent Beta (OSS Red Team)",
|
|
268
|
+
"mode": "oss_scout",
|
|
269
|
+
"scope_id": scope_id,
|
|
270
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
271
|
+
"falsification_claims": [
|
|
272
|
+
{
|
|
273
|
+
"claim_id": "BETA-S01",
|
|
274
|
+
"tag": "VERIFIED",
|
|
275
|
+
"statement": "Candidate repository has single maintainer with 9-month lull in commit history.",
|
|
276
|
+
"source_hash": shash,
|
|
277
|
+
"source_url": "https://github.com/example/rust-raft",
|
|
278
|
+
"verbatim_quote": "Zero-dependency Raft implementation with 150k ops/sec throughput under Apache-2.0.",
|
|
279
|
+
"severity": "LOW"
|
|
280
|
+
}
|
|
281
|
+
],
|
|
282
|
+
"methodological_critiques": [
|
|
283
|
+
{
|
|
284
|
+
"target_assertion": "Rust-Raft achieves 150k ops/sec with zero external dependencies.",
|
|
285
|
+
"critique": "Throughput degrades during log compaction due to unbuffered disk sync.",
|
|
286
|
+
"evidence_hash": shash
|
|
287
|
+
}
|
|
288
|
+
],
|
|
289
|
+
"negative_knowledge": []
|
|
290
|
+
}
|
|
291
|
+
else:
|
|
292
|
+
sample_content = "# PCIe Bus Saturation Study\nIn continuous batch streaming, PCIe 4.0 transfers introduce a 650ms delay, yielding total latency > 800ms."
|
|
293
|
+
shash = self.hasher.store_source("https://arxiv.org/abs/2406.9999", sample_content, "PCIe Bottlenecks")
|
|
294
|
+
|
|
295
|
+
dossier = {
|
|
296
|
+
"agent": "Agent Beta (Red Team)",
|
|
297
|
+
"scope_id": scope_id,
|
|
298
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
299
|
+
"falsification_claims": [
|
|
300
|
+
{
|
|
301
|
+
"claim_id": "BETA-C01",
|
|
302
|
+
"tag": "VERIFIED",
|
|
303
|
+
"statement": "Batch streaming incurs a 650ms PCIe transfer delay under production loads.",
|
|
304
|
+
"source_hash": shash,
|
|
305
|
+
"source_url": "https://arxiv.org/abs/2406.9999",
|
|
306
|
+
"verbatim_quote": "In continuous batch streaming, PCIe 4.0 transfers introduce a 650ms delay, yielding total latency > 800ms."
|
|
307
|
+
}
|
|
308
|
+
],
|
|
309
|
+
"methodological_critiques": [
|
|
310
|
+
{
|
|
311
|
+
"target_assertion": "FPGA-accelerated Poseidon provers achieve sub-200ms latency on 2^20 constraints.",
|
|
312
|
+
"critique": "Benchmark isolates compute kernel and ignores host-to-device PCIe latency in pipelined batches.",
|
|
313
|
+
"evidence_hash": shash
|
|
314
|
+
}
|
|
315
|
+
],
|
|
316
|
+
"negative_knowledge": [
|
|
317
|
+
{
|
|
318
|
+
"query": "Zero-latency PCIe streaming ZK provers",
|
|
319
|
+
"finding": "No architecture eliminates bus transfer overhead without on-chip memory > 128GB."
|
|
320
|
+
}
|
|
321
|
+
]
|
|
322
|
+
}
|
|
211
323
|
else:
|
|
212
|
-
prompt = f"Run Agent Beta for scope: {json.dumps(scope)}. Save findings to {scope_id} scratchpad."
|
|
213
|
-
|
|
324
|
+
prompt = f"Run Agent Beta ({self.mode} mode) for scope: {json.dumps(scope)}. Engine: {self.engine}. Depth: {self.depth}. Save findings to {scope_id} scratchpad."
|
|
325
|
+
if self.mode == "audit":
|
|
326
|
+
system_prompt = self.prompts_dir / "agent_code_auditor.md"
|
|
327
|
+
elif self.mode == "scout":
|
|
328
|
+
system_prompt = self.prompts_dir / "agent_oss_scout.md"
|
|
329
|
+
else:
|
|
330
|
+
system_prompt = self.prompts_dir / "agent_beta_antithesis.md"
|
|
214
331
|
self.run_claude_process(prompt, system_prompt_file=system_prompt)
|
|
215
332
|
dossier_path = self.state_machine.get_scope_dir(scope_id) / "beta_dossier.json"
|
|
216
333
|
with open(dossier_path, "r", encoding="utf-8") as f:
|
|
@@ -243,7 +360,8 @@ Output ONLY valid JSON representing the scope decomposition conforming to prompt
|
|
|
243
360
|
"""Full end-to-end execution loop."""
|
|
244
361
|
start_time = datetime.now(timezone.utc)
|
|
245
362
|
print("=" * 70)
|
|
246
|
-
print("🌟 EPISTEMIC SWARM: HIGH-INTEGRITY RESEARCH HARNESS")
|
|
363
|
+
print(f"🌟 EPISTEMIC SWARM: HIGH-INTEGRITY RESEARCH HARNESS [{self.mode.upper()} MODE]")
|
|
364
|
+
print(f" Engine: {self.engine.upper()} | Depth: {self.depth} | Dir: {self.base_dir}")
|
|
247
365
|
print("=" * 70)
|
|
248
366
|
|
|
249
367
|
# 1. Orchestrate
|
|
@@ -270,20 +388,28 @@ Output ONLY valid JSON representing the scope decomposition conforming to prompt
|
|
|
270
388
|
self.execute_scope_dialectic(scope)
|
|
271
389
|
|
|
272
390
|
# 3. Master Synthesis Compilation
|
|
273
|
-
print("\n📜 [Phase 5: Master Synthesis] Aggregating
|
|
274
|
-
self._compile_master_synthesis(objective)
|
|
391
|
+
print(f"\n📜 [Phase 5: Master Synthesis] Aggregating {self.mode.upper()} dossiers...")
|
|
392
|
+
report_path = self._compile_master_synthesis(objective)
|
|
275
393
|
self.state_machine.update_session_status(SessionStatus.COMPLETED)
|
|
276
394
|
|
|
277
395
|
duration = (datetime.now(timezone.utc) - start_time).total_seconds()
|
|
278
|
-
print(f"\n🎉
|
|
396
|
+
print(f"\n🎉 Swarm run completed in {duration:.1f}s. Report: {report_path}")
|
|
279
397
|
|
|
280
|
-
def _compile_master_synthesis(self, objective: str):
|
|
398
|
+
def _compile_master_synthesis(self, objective: str) -> Path:
|
|
281
399
|
manifest = self.state_machine.load_global_manifest()
|
|
400
|
+
mode_titles = {
|
|
401
|
+
"audit": "Codebase Architectural & Security Audit",
|
|
402
|
+
"scout": "Open-Source Software Discovery & Clean-Room Blueprint",
|
|
403
|
+
"hybrid": "Hybrid Codebase & Literature Epistemic Report",
|
|
404
|
+
"research": "Master Epistemic Research Report"
|
|
405
|
+
}
|
|
406
|
+
title = mode_titles.get(self.mode, "Master Epistemic Research Report")
|
|
407
|
+
|
|
282
408
|
synthesis_lines = [
|
|
283
|
-
f"#
|
|
284
|
-
f"**Session ID**: `{manifest['session_id']}` | **Generated**: `{manifest['updated_at']}`\n",
|
|
409
|
+
f"# {title}: {objective}\n",
|
|
410
|
+
f"**Session ID**: `{manifest['session_id']}` | **Mode**: `{self.mode.upper()}` | **Engine**: `{self.engine}` | **Generated**: `{manifest['updated_at']}`\n",
|
|
285
411
|
"## Executive Summary",
|
|
286
|
-
"This
|
|
412
|
+
f"This brief was compiled using the Epistemic Swarm dialectic harness ({self.mode} mode). Every factual statement carries an empirical verification pointer backed by a content-addressed raw document cache.\n",
|
|
287
413
|
"## Scope Findings & Dialectic Balance Sheets\n"
|
|
288
414
|
]
|
|
289
415
|
|
|
@@ -319,6 +445,20 @@ Output ONLY valid JSON representing the scope decomposition conforming to prompt
|
|
|
319
445
|
with open(final_path, "w", encoding="utf-8") as f:
|
|
320
446
|
f.write("\n".join(synthesis_lines))
|
|
321
447
|
|
|
448
|
+
# Also write specialized report files for audit and scout modes
|
|
449
|
+
if self.mode == "audit":
|
|
450
|
+
audit_path = self.base_dir / "code_audit_report.md"
|
|
451
|
+
with open(audit_path, "w", encoding="utf-8") as f:
|
|
452
|
+
f.write("\n".join(synthesis_lines))
|
|
453
|
+
return audit_path
|
|
454
|
+
elif self.mode == "scout":
|
|
455
|
+
scout_path = self.base_dir / "oss_scout_report.md"
|
|
456
|
+
with open(scout_path, "w", encoding="utf-8") as f:
|
|
457
|
+
f.write("\n".join(synthesis_lines))
|
|
458
|
+
return scout_path
|
|
459
|
+
|
|
460
|
+
return final_path
|
|
461
|
+
|
|
322
462
|
|
|
323
463
|
def main():
|
|
324
464
|
parser = argparse.ArgumentParser(description="Epistemic Swarm Dialectic Research Runner")
|
|
@@ -326,10 +466,19 @@ def main():
|
|
|
326
466
|
parser.add_argument("--frontier", type=str, help="Path to settled frontier.json from /grilling")
|
|
327
467
|
parser.add_argument("--mock-claude", action="store_true", help="Run with synthetic test data without invoking Claude Code")
|
|
328
468
|
parser.add_argument("--dir", default=".research", help="Path to .research workspace")
|
|
469
|
+
parser.add_argument("--mode", choices=["research", "audit", "scout", "hybrid"], default=None, help="Operating mode")
|
|
470
|
+
parser.add_argument("--engine", choices=["duckduckgo", "brave", "firecrawl", "searxng"], default=None, help="Search engine")
|
|
471
|
+
parser.add_argument("--depth", "--iterations", type=int, default=None, help="Max dialectic depth / iterations")
|
|
329
472
|
|
|
330
473
|
args = parser.parse_args()
|
|
331
474
|
frontier_path = Path(args.frontier) if args.frontier else None
|
|
332
|
-
runner = SwarmRunner(
|
|
475
|
+
runner = SwarmRunner(
|
|
476
|
+
base_dir=Path(args.dir),
|
|
477
|
+
mock_mode=args.mock_claude,
|
|
478
|
+
mode=args.mode,
|
|
479
|
+
engine=args.engine,
|
|
480
|
+
depth=args.depth
|
|
481
|
+
)
|
|
333
482
|
runner.run_swarm(args.objective, frontier_file=frontier_path)
|
|
334
483
|
|
|
335
484
|
|
|
Binary file
|
|
@@ -201,7 +201,44 @@ In our experiments, the 70B parameter model was trained on 15.0 trillion tokens.
|
|
|
201
201
|
self.assertIn("iumbtems", pkg.get("bin", {}))
|
|
202
202
|
self.assertTrue((PROJECT_ROOT / pkg["bin"]["iumbtems"]).exists())
|
|
203
203
|
|
|
204
|
+
def test_config_manager_load_and_save(self):
|
|
205
|
+
from skills.swarm_config.configure import load_config, save_config
|
|
206
|
+
cfg = load_config(str(self.test_dir))
|
|
207
|
+
self.assertEqual(cfg["search_engine"], "duckduckgo")
|
|
208
|
+
self.assertEqual(cfg["mode"], "research")
|
|
209
|
+
|
|
210
|
+
cfg["search_engine"] = "brave"
|
|
211
|
+
cfg["mode"] = "audit"
|
|
212
|
+
cfg["max_iterations"] = 3
|
|
213
|
+
save_config(cfg, str(self.test_dir))
|
|
214
|
+
|
|
215
|
+
reloaded = load_config(str(self.test_dir))
|
|
216
|
+
self.assertEqual(reloaded["search_engine"], "brave")
|
|
217
|
+
self.assertEqual(reloaded["mode"], "audit")
|
|
218
|
+
self.assertEqual(reloaded["max_iterations"], 3)
|
|
219
|
+
|
|
220
|
+
def test_mock_code_audit_mode(self):
|
|
221
|
+
runner = SwarmRunner(base_dir=self.test_dir, mock_mode=True, mode="audit")
|
|
222
|
+
runner.run_swarm("Audit state machine concurrency")
|
|
223
|
+
|
|
224
|
+
audit_report = self.test_dir / "code_audit_report.md"
|
|
225
|
+
self.assertTrue(audit_report.exists())
|
|
226
|
+
with open(audit_report, "r") as f:
|
|
227
|
+
content = f.read()
|
|
228
|
+
self.assertIn("Codebase Architectural & Security Audit", content)
|
|
229
|
+
|
|
230
|
+
def test_mock_oss_scout_mode(self):
|
|
231
|
+
runner = SwarmRunner(base_dir=self.test_dir, mock_mode=True, mode="scout")
|
|
232
|
+
runner.run_swarm("Scout Raft consensus libraries")
|
|
233
|
+
|
|
234
|
+
scout_report = self.test_dir / "oss_scout_report.md"
|
|
235
|
+
self.assertTrue(scout_report.exists())
|
|
236
|
+
with open(scout_report, "r") as f:
|
|
237
|
+
content = f.read()
|
|
238
|
+
self.assertIn("Open-Source Software Discovery", content)
|
|
239
|
+
|
|
204
240
|
|
|
205
241
|
if __name__ == "__main__":
|
|
206
242
|
unittest.main()
|
|
207
243
|
|
|
244
|
+
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-audit
|
|
3
|
+
description: Deep dialectic codebase auditing skill. Deploys architectural thesis vs adversarial red-team antithesis to discover security vulnerabilities, race conditions, resource leaks, and architectural flaws with exact line-level proof.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Dialectic Codebase Audit Engine
|
|
7
|
+
|
|
8
|
+
Perform exhaustive, evidence-backed security, performance, and architectural audits of codebases.
|
|
9
|
+
Unlike superficial linting or single-pass code reviews, this skill pairs a **Structural Architect (Thesis)** with an **Adversarial Red-Teamer (Antithesis)** to rigorously stress-test codebase assumptions.
|
|
10
|
+
|
|
11
|
+
## 1. Invoking a Codebase Audit
|
|
12
|
+
|
|
13
|
+
Audit the entire repository:
|
|
14
|
+
```bash
|
|
15
|
+
iumbtems audit "Full repository architecture and vulnerability audit"
|
|
16
|
+
```
|
|
17
|
+
Or via npx:
|
|
18
|
+
```bash
|
|
19
|
+
npx @heretek-ai/epistemic-swarm audit "Audit runner/ and skills/ for concurrency and injection vectors"
|
|
20
|
+
```
|
|
21
|
+
Or directly with the python runner:
|
|
22
|
+
```bash
|
|
23
|
+
python3 runner/research_swarm.py --mode audit --objective "Audit security boundaries and memory lifecycle"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 2. Dialectic Audit Protocol
|
|
27
|
+
|
|
28
|
+
1. **Phase 1: Architectural Invariant Mapping (Alpha)**
|
|
29
|
+
- Maps module boundaries, call graphs, state transition lifecycles, and synchronization locks.
|
|
30
|
+
- Extracts invariants and documents design guarantees with line pointers: `[PATH: src/auth.py#L45-L60]`.
|
|
31
|
+
|
|
32
|
+
2. **Phase 2: Adversarial Red-Teaming (Beta)**
|
|
33
|
+
- Actively searches for exploit vectors: injection flaws (CWE-78, CWE-89), race conditions (CWE-362), unhandled error paths, resource exhaustion, and memory leaks.
|
|
34
|
+
- Constructs concrete proof-of-concept failure sequences attacking Alpha's assumed invariants.
|
|
35
|
+
|
|
36
|
+
3. **Phase 3: Epistemic Code Verification**
|
|
37
|
+
- Mathematically verifies that all cited files and lines exist on disk and accurately reproduce the target code.
|
|
38
|
+
- Penalizes speculative or hallucinated line references.
|
|
39
|
+
- Produces `.research/code_audit_report.md` and `.research/code_audit_dossier.json`.
|
|
40
|
+
|
|
41
|
+
## 3. Evidence Standards
|
|
42
|
+
|
|
43
|
+
- **Strict Line Pointers**: Every vulnerability or architectural observation must specify `file:///path/to/file#L<start>-L<end>`.
|
|
44
|
+
- **Verbatim Snippets**: Code excerpts must match the local repository verbatim.
|
|
45
|
+
- **Actionable Remediation**: Every vulnerability must include a concrete patch diff or refactoring blueprint.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: epistemic_search
|
|
3
|
+
description: High-integrity web search and document fetch skill with automatic SHA-256 content caching. Use when searching the web, retrieving primary sources, or fetching documentation while enforcing epistemic integrity.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Epistemic Search & Verifiable Source Fetching
|
|
7
|
+
|
|
8
|
+
This skill provides zero-API-key web search (DuckDuckGo Lite) and content-addressed source fetching.
|
|
9
|
+
Every fetched web page is automatically saved with its SHA-256 fingerprint into `.research/sources/<sha256>.md` for mathematical auditability.
|
|
10
|
+
|
|
11
|
+
## 1. Web Search (No API Key Required)
|
|
12
|
+
|
|
13
|
+
Run search with a query:
|
|
14
|
+
```bash
|
|
15
|
+
python3 skills/epistemic_search/scripts/search.py "YOUR SEARCH QUERY"
|
|
16
|
+
```
|
|
17
|
+
Or with JSON piping:
|
|
18
|
+
```bash
|
|
19
|
+
echo '{"query": "zk-SNARK hardware benchmarks", "allowed_domains": ["arxiv.org", "eprint.iacr.org"]}' | python3 skills/epistemic_search/scripts/search.py
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Outputs `<search_results>` XML containing title, URL, and snippets.
|
|
23
|
+
|
|
24
|
+
## 2. Verifiable Web Fetch & Automatic Caching
|
|
25
|
+
|
|
26
|
+
Fetch any web page or documentation:
|
|
27
|
+
```bash
|
|
28
|
+
python3 skills/epistemic_search/scripts/fetch.py "https://example.com/paper.html"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The script outputs clean markdown and automatically persists the raw source into `.research/sources/<sha256>.md`.
|
|
32
|
+
|
|
33
|
+
Use the resulting SHA-256 hash when making claims:
|
|
34
|
+
`[VERIFIED: <first_16_chars_of_hash>]`
|
|
35
|
+
Ensure any cited quotes are exact verbatim substrings from the cached document.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Epistemic Search module
|