@heretek-ai/epistemic-swarm 0.2.2 → 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 +53 -8
  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 +58 -3
  30. package/config/searxng_mcp.py +42 -83
  31. package/extensions/pi/index.js +196 -28
  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 +335 -118
  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 +173 -15
  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
@@ -0,0 +1,200 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Brainstorm scaffolding: dynamic context ingestion + domain model extraction.
4
+ Read-only. Never exceeds a capped budget. Used by /brainstorming skill and
5
+ runner/research_swarm.py --mode brainstorm.
6
+ """
7
+
8
+ import argparse
9
+ import json
10
+ import subprocess
11
+ import sys
12
+ from datetime import datetime, timezone
13
+ from pathlib import Path
14
+
15
+ PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent.parent
16
+ STACK_FILES = [
17
+ "package.json",
18
+ "pyproject.toml",
19
+ "Cargo.toml",
20
+ "go.mod",
21
+ "requirements.txt",
22
+ "requirements-dev.txt",
23
+ "bun.lock",
24
+ "pom.xml",
25
+ ]
26
+ DOC_CANDIDATES = [
27
+ "README.md",
28
+ "AGENTS.md",
29
+ "GEMINI.md",
30
+ "SYSTEM.md",
31
+ "docs/SYSTEM_ARCHITECTURE.md",
32
+ "docs/DISTRIBUTION_STRATEGY.md",
33
+ ]
34
+ SKIP_DIRS = {
35
+ ".git",
36
+ "node_modules",
37
+ "__pycache__",
38
+ ".venv",
39
+ "venv",
40
+ "dist",
41
+ "build",
42
+ ".research",
43
+ "target",
44
+ ".next",
45
+ }
46
+
47
+
48
+ def sh(cmd, cwd=None):
49
+ try:
50
+ r = subprocess.run(
51
+ cmd,
52
+ capture_output=True,
53
+ text=True,
54
+ cwd=str(cwd or PROJECT_ROOT),
55
+ timeout=30,
56
+ )
57
+ return (r.stdout or "").strip()
58
+ except Exception:
59
+ return ""
60
+
61
+
62
+ def project_tree(depth=3, limit=200):
63
+ entries = []
64
+ root = PROJECT_ROOT
65
+ for dirpath, dirnames, filenames in __import__("os").walk(root):
66
+ dirnames[:] = [d for d in dirnames if d not in SKIP_DIRS]
67
+ rel = Path(dirpath).relative_to(root)
68
+ d = len(rel.parts) if str(rel) != "." else 0
69
+ if d > depth:
70
+ dirnames[:] = []
71
+ continue
72
+ for f in sorted(filenames)[:50]:
73
+ entries.append(str(rel / f) if str(rel) != "." else f)
74
+ if len(entries) >= limit:
75
+ return entries
76
+ return entries
77
+
78
+
79
+ def read_capped(path, cap=6000):
80
+ p = PROJECT_ROOT / path
81
+ if not p.exists() or not p.is_file():
82
+ return ""
83
+ try:
84
+ return p.read_text(encoding="utf-8", errors="replace")[:cap]
85
+ except Exception:
86
+ return ""
87
+
88
+
89
+ def grep_todos(limit=30):
90
+ out = sh(
91
+ [
92
+ "git",
93
+ "grep",
94
+ "-n",
95
+ "-E",
96
+ "TODO|FIXME|HACK|XXX",
97
+ "--",
98
+ ".",
99
+ ":(exclude).research",
100
+ ]
101
+ )
102
+ if not out:
103
+ # fallback without git
104
+ out = sh(
105
+ [
106
+ "grep",
107
+ "-rn",
108
+ "-E",
109
+ "TODO|FIXME|HACK|XXX",
110
+ "--include=*.py",
111
+ "--include=*.ts",
112
+ "--include=*.js",
113
+ "--include=*.md",
114
+ ".",
115
+ ]
116
+ )
117
+ lines = [l for l in out.splitlines() if ".research" not in l][:limit]
118
+ return lines
119
+
120
+
121
+ def detect_stack():
122
+ found = []
123
+ for f in STACK_FILES:
124
+ if (PROJECT_ROOT / f).exists():
125
+ found.append(f)
126
+ return found
127
+
128
+
129
+ def build_domain_model(objective, full=True):
130
+ tree = project_tree(depth=3 if full else 1, limit=200 if full else 60)
131
+ docs = {
132
+ d: read_capped(d, 4000 if full else 1500)
133
+ for d in DOC_CANDIDATES
134
+ if (PROJECT_ROOT / d).exists()
135
+ }
136
+ git_log = sh(["git", "log", "--oneline", "-20"]) if full else ""
137
+ git_status = sh(["git", "status", "--short"])
138
+ todos = grep_todos(30 if full else 10)
139
+ stack = detect_stack()
140
+ model = {
141
+ "objective": objective,
142
+ "generated_at": datetime.now(timezone.utc).isoformat(),
143
+ "domain": "",
144
+ "entities": [],
145
+ "constraints": [],
146
+ "stack": stack,
147
+ "tree_sample": tree[:80],
148
+ "docs_seen": sorted(docs.keys()),
149
+ "git_log": git_log.splitlines()[:20],
150
+ "git_status": git_status.splitlines()[:20],
151
+ "open_loops": todos,
152
+ }
153
+ return model, docs
154
+
155
+
156
+ def main():
157
+ ap = argparse.ArgumentParser(description="IUMBTEMS brainstorm context ingestion")
158
+ ap.add_argument("--objective", required=True)
159
+ ap.add_argument("--show-context", action="store_true")
160
+ ap.add_argument(
161
+ "--export", default="", help="Export domain_model.json to this path"
162
+ )
163
+ ap.add_argument(
164
+ "--shallow",
165
+ action="store_true",
166
+ help="Shallow mode: README + top-level only (low context budget)",
167
+ )
168
+ args = ap.parse_args()
169
+
170
+ model, docs = build_domain_model(args.objective, full=not args.shallow)
171
+
172
+ if args.show_context or not args.export:
173
+ print(f"\n🧠 [Brainstorm] Objective: {args.objective}")
174
+ print(f"📁 Tree entries sampled: {len(model['tree_sample'])}")
175
+ print(f"📄 Docs ingested: {', '.join(model['docs_seen']) or 'none'}")
176
+ print(f"🧱 Stack signals: {', '.join(model['stack']) or 'none'}")
177
+ print(f"📝 Open loops: {len(model['open_loops'])}")
178
+ for t in model["open_loops"][:10]:
179
+ print(f" - {t[:160]}")
180
+ if model["git_log"]:
181
+ print("🕘 Recent history:")
182
+ for line in model["git_log"][:10]:
183
+ print(f" {line[:140]}")
184
+ print("\nDomain model (fill domain/entities/constraints before ideating):")
185
+ print(
186
+ json.dumps(
187
+ {k: model[k] for k in ("domain", "entities", "constraints", "stack")},
188
+ indent=2,
189
+ )
190
+ )
191
+
192
+ if args.export:
193
+ out = Path(args.export)
194
+ out.parent.mkdir(parents=True, exist_ok=True)
195
+ out.write_text(json.dumps(model, indent=2), encoding="utf-8")
196
+ print(f"✅ Domain model exported to {out}")
197
+
198
+
199
+ if __name__ == "__main__":
200
+ main()
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: swarm-config
3
- description: Dynamic configuration and settings skill for the Epistemic Swarm research harness. Manage search engines, research depth, dialectic iterations, operating modes (research, audit, scout), and license filters.
3
+ description: Dynamic configuration and settings skill for the Epistemic Swarm research harness. Manage search engines, research depth, dialectic iterations, operating modes (research, audit, scout, hybrid, brainstorm), and license filters.
4
4
  ---
5
5
 
6
6
  # Epistemic Swarm Configuration & Parameter Tuning
@@ -14,15 +14,33 @@ DEFAULT_CONFIG: Dict[str, Any] = {
14
14
  "search_engine": "duckduckgo",
15
15
  "max_iterations": 2,
16
16
  "divergence_threshold": 0.75,
17
- "mode": "research", # "research", "audit", "scout", "hybrid"
17
+ "mode": "research", # "research", "audit", "scout", "hybrid", "brainstorm"
18
18
  "cache_raw_markdown": True,
19
19
  "license_whitelist": ["MIT", "Apache-2.0", "BSD-3-Clause", "ISC"],
20
- "output_dir": ".research"
20
+ "output_dir": ".research",
21
+ # Scope allocation policy (Stream F): "dag" = legacy dependency-first
22
+ # order; "auction" = Frontier Markets (highest expected-information-gain
23
+ # bid first). Default "dag" preserves existing behavior exactly.
24
+ "allocation": "dag",
25
+ # Regulated Domain Pack id (Stream G) or null for the legacy constitution.
26
+ # Loaded via runner.refinement.load_domain_pack (config/domain_packs/).
27
+ "domain_pack": None,
28
+ # Per-agent backends. Asymmetry is the point (Stream E): Alpha and Beta on
29
+ # different model families/weights probe divergence that prompt-level
30
+ # red-teaming cannot reach. `backend` is a command list, not just a model
31
+ # string, because cross-FAMILY means non-Claude processes.
32
+ # mock mode never builds or spawns these commands.
33
+ "agents": {
34
+ "alpha": {"backend": ["claude", "-p"], "model": None},
35
+ "beta": {"backend": ["claude", "-p"], "model": None},
36
+ },
21
37
  }
22
38
 
39
+
23
40
  def get_config_path(base_dir: str = ".research") -> Path:
24
41
  return Path(base_dir) / "config.json"
25
42
 
43
+
26
44
  def load_config(base_dir: str = ".research") -> Dict[str, Any]:
27
45
  cfg_file = get_config_path(base_dir)
28
46
  if not cfg_file.exists():
@@ -34,9 +52,12 @@ def load_config(base_dir: str = ".research") -> Dict[str, Any]:
34
52
  merged.update(data)
35
53
  return merged
36
54
  except Exception as e:
37
- sys.stderr.write(f"[swarm-config] Warning: Failed to parse {cfg_file}: {e}. Using defaults.\n")
55
+ sys.stderr.write(
56
+ f"[swarm-config] Warning: Failed to parse {cfg_file}: {e}. Using defaults.\n"
57
+ )
38
58
  return dict(DEFAULT_CONFIG)
39
59
 
60
+
40
61
  def save_config(cfg: Dict[str, Any], base_dir: str = ".research") -> Path:
41
62
  target_dir = Path(base_dir)
42
63
  target_dir.mkdir(parents=True, exist_ok=True)
@@ -45,18 +66,24 @@ def save_config(cfg: Dict[str, Any], base_dir: str = ".research") -> Path:
45
66
  json.dump(cfg, f, indent=2)
46
67
  return cfg_file
47
68
 
69
+
48
70
  def display_config(cfg: Dict[str, Any]):
49
71
  print("\n⚙️ EPISTEMIC SWARM ACTIVE CONFIGURATION")
50
72
  print("========================================")
51
- print(f" 🔍 Primary Search Engine: {cfg.get('search_engine', 'duckduckgo').upper()}")
73
+ print(
74
+ f" 🔍 Primary Search Engine: {cfg.get('search_engine', 'duckduckgo').upper()}"
75
+ )
52
76
  print(f" 🔄 Max Iterations (Depth): {cfg.get('max_iterations', 2)}")
53
77
  print(f" ⚖️ Divergence Threshold: {cfg.get('divergence_threshold', 0.75)}")
54
78
  print(f" 🎯 Operating Mode: {cfg.get('mode', 'research').upper()}")
55
- print(f" 💾 Raw Markdown Caching: {'ENABLED' if cfg.get('cache_raw_markdown', True) else 'DISABLED'}")
79
+ print(
80
+ f" 💾 Raw Markdown Caching: {'ENABLED' if cfg.get('cache_raw_markdown', True) else 'DISABLED'}"
81
+ )
56
82
  print(f" 📜 License Whitelist: {', '.join(cfg.get('license_whitelist', []))}")
57
83
  print(f" 📁 Output Directory: {cfg.get('output_dir', '.research')}")
58
84
  print("========================================\n")
59
85
 
86
+
60
87
  def run_interactive(cfg: Dict[str, Any]) -> Dict[str, Any]:
61
88
  print("\n🔧 Epistemic Swarm Interactive Configuration Setup")
62
89
  print("--------------------------------------------------")
@@ -89,10 +116,11 @@ def run_interactive(cfg: Dict[str, Any]) -> Dict[str, Any]:
89
116
 
90
117
  # 3. Operating mode
91
118
  print("\nSelect Primary Operating Mode:")
92
- print(" 1) research — Empirical web & literature synthesis")
93
- print(" 2) audit — Deep codebase architecture & vulnerability audit")
94
- print(" 3) scout — Open-source software discovery & clean-room harvesting")
95
- print(" 4) hybrid — Combined codebase audit + web research")
119
+ print(" 1) research — Empirical web & literature synthesis")
120
+ print(" 2) audit — Deep codebase architecture & vulnerability audit")
121
+ print(" 3) scout — Open-source software discovery & clean-room harvesting")
122
+ print(" 4) hybrid — Combined codebase audit + web research")
123
+ print(" 5) brainstorm — Lateral creative ideation & what-if exploration")
96
124
  mode_choice = input(f"Choice [current: {cfg['mode']}]: ").strip()
97
125
  if mode_choice == "1":
98
126
  cfg["mode"] = "research"
@@ -102,9 +130,12 @@ def run_interactive(cfg: Dict[str, Any]) -> Dict[str, Any]:
102
130
  cfg["mode"] = "scout"
103
131
  elif mode_choice == "4":
104
132
  cfg["mode"] = "hybrid"
133
+ elif mode_choice == "5":
134
+ cfg["mode"] = "brainstorm"
105
135
 
106
136
  return cfg
107
137
 
138
+
108
139
  def main():
109
140
  cfg = load_config()
110
141
  args = sys.argv[1:]
@@ -114,7 +145,9 @@ def main():
114
145
  if not args:
115
146
  print("To edit settings, run:")
116
147
  print(" python3 skills/swarm_config/configure.py --interactive")
117
- print(" python3 skills/swarm_config/configure.py --engine duckduckgo --depth 3 --mode audit\n")
148
+ print(
149
+ " python3 skills/swarm_config/configure.py --engine duckduckgo --depth 3 --mode audit\n"
150
+ )
118
151
  return
119
152
 
120
153
  if "--interactive" in args or "-i" in args:
@@ -143,7 +176,7 @@ def main():
143
176
  idx += 1
144
177
  elif arg in ("--mode", "-m") and idx + 1 < len(args):
145
178
  mode = args[idx + 1].lower()
146
- if mode in ("research", "audit", "scout", "hybrid"):
179
+ if mode in ("research", "audit", "scout", "hybrid", "brainstorm"):
147
180
  cfg["mode"] = mode
148
181
  modified = True
149
182
  idx += 1
@@ -163,5 +196,6 @@ def main():
163
196
  else:
164
197
  display_config(cfg)
165
198
 
199
+
166
200
  if __name__ == "__main__":
167
201
  main()