@heretek-ai/epistemic-swarm 0.7.19 → 0.7.21

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 (81) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +23 -2
  3. package/package.json +1 -1
  4. package/plugins/antigravity/plugin.json +1 -1
  5. package/plugins/antigravity/rules/AGENTS.md +5 -3
  6. package/plugins/opencode/config-io.js +55 -12
  7. package/plugins/opencode/index.js +611 -0
  8. package/plugins/opencode/tui.js +278 -6
  9. package/runner/__pycache__/__init__.cpython-311.pyc +0 -0
  10. package/runner/__pycache__/auctioneer.cpython-311.pyc +0 -0
  11. package/runner/__pycache__/auditor_engine.cpython-311.pyc +0 -0
  12. package/runner/__pycache__/claim_store.cpython-311.pyc +0 -0
  13. package/runner/__pycache__/claim_witness.cpython-311.pyc +0 -0
  14. package/runner/__pycache__/darkharvest_claims.cpython-311.pyc +0 -0
  15. package/runner/__pycache__/errors.cpython-311.pyc +0 -0
  16. package/runner/__pycache__/living_dossiers.cpython-311.pyc +0 -0
  17. package/runner/__pycache__/mcp_protocol.cpython-311.pyc +0 -0
  18. package/runner/__pycache__/mcp_server.cpython-311.pyc +0 -0
  19. package/runner/__pycache__/path_safety.cpython-311.pyc +0 -0
  20. package/runner/__pycache__/pcrb.cpython-311.pyc +0 -0
  21. package/runner/__pycache__/pcrb_verify.cpython-311.pyc +0 -0
  22. package/runner/__pycache__/preflight.cpython-311.pyc +0 -0
  23. package/runner/__pycache__/refinement.cpython-311.pyc +0 -0
  24. package/runner/__pycache__/research_swarm.cpython-311.pyc +0 -0
  25. package/runner/__pycache__/retrieval_log.cpython-311.pyc +0 -0
  26. package/runner/__pycache__/schema_validate.cpython-311.pyc +0 -0
  27. package/runner/__pycache__/schemas.cpython-311.pyc +0 -0
  28. package/runner/__pycache__/state_machine.cpython-311.pyc +0 -0
  29. package/runner/mcp_server.py +81 -10
  30. package/runner/research_swarm.py +12 -2
  31. package/runner/schemas.py +18 -0
  32. package/runner/tests/__pycache__/test_antigravity_plugin.cpython-311.pyc +0 -0
  33. package/runner/tests/__pycache__/test_auction_order.cpython-311.pyc +0 -0
  34. package/runner/tests/__pycache__/test_backends.cpython-311.pyc +0 -0
  35. package/runner/tests/__pycache__/test_bet1_spike.cpython-311.pyc +0 -0
  36. package/runner/tests/__pycache__/test_claim_store.cpython-311.pyc +0 -0
  37. package/runner/tests/__pycache__/test_claim_witness.cpython-311.pyc +0 -0
  38. package/runner/tests/__pycache__/test_claude_plugin.cpython-311.pyc +0 -0
  39. package/runner/tests/__pycache__/test_config_schema.cpython-311.pyc +0 -0
  40. package/runner/tests/__pycache__/test_contract_tooling.cpython-311.pyc +0 -0
  41. package/runner/tests/__pycache__/test_darkharvest_audit.cpython-311.pyc +0 -0
  42. package/runner/tests/__pycache__/test_domain_packs.cpython-311.pyc +0 -0
  43. package/runner/tests/__pycache__/test_dossier_contract.cpython-311.pyc +0 -0
  44. package/runner/tests/__pycache__/test_factory.cpython-311.pyc +0 -0
  45. package/runner/tests/__pycache__/test_fleet_seam.cpython-311.pyc +0 -0
  46. package/runner/tests/__pycache__/test_frontier_concurrency.cpython-311.pyc +0 -0
  47. package/runner/tests/__pycache__/test_frontier_mirror_standalone.cpython-311.pyc +0 -0
  48. package/runner/tests/__pycache__/test_grounding.cpython-311.pyc +0 -0
  49. package/runner/tests/__pycache__/test_living_dossiers.cpython-311.pyc +0 -0
  50. package/runner/tests/__pycache__/test_manifest_concurrency.cpython-311.pyc +0 -0
  51. package/runner/tests/__pycache__/test_mcp_server.cpython-311.pyc +0 -0
  52. package/runner/tests/__pycache__/test_opencode_ux.cpython-311.pyc +0 -0
  53. package/runner/tests/__pycache__/test_opencode_v2_registrars.cpython-311.pyc +0 -0
  54. package/runner/tests/__pycache__/test_pcrb.cpython-311.pyc +0 -0
  55. package/runner/tests/__pycache__/test_refinement.cpython-311.pyc +0 -0
  56. package/runner/tests/__pycache__/test_search_anomaly.cpython-311.pyc +0 -0
  57. package/runner/tests/__pycache__/test_search_provider.cpython-311.pyc +0 -0
  58. package/runner/tests/__pycache__/test_search_provider_plugin.cpython-311.pyc +0 -0
  59. package/runner/tests/__pycache__/test_swarm.cpython-311.pyc +0 -0
  60. package/runner/tests/__pycache__/test_swarm_config.cpython-311.pyc +0 -0
  61. package/runner/tests/__pycache__/test_sweep_regressions.cpython-311.pyc +0 -0
  62. package/runner/tests/__pycache__/test_webcache.cpython-311.pyc +0 -0
  63. package/runner/tests/test_config_schema.py +106 -0
  64. package/runner/tests/test_opencode_ux.py +462 -7
  65. package/runner/tests/test_opencode_v2_registrars.py +1112 -3
  66. package/runner/tests/test_swarm_config.py +21 -0
  67. package/schemas/config.schema.json +11 -0
  68. package/scripts/__pycache__/bet1_advisory_spike.cpython-311.pyc +0 -0
  69. package/scripts/__pycache__/build_adapters.cpython-311.pyc +0 -0
  70. package/scripts/__pycache__/check_docs.cpython-311.pyc +0 -0
  71. package/scripts/__pycache__/divergence_experiment.cpython-311.pyc +0 -0
  72. package/scripts/__pycache__/gen_schemas.cpython-311.pyc +0 -0
  73. package/skills/epistemic_search/scripts/__pycache__/search.cpython-311.pyc +0 -0
  74. package/skills/grilling/__pycache__/__init__.cpython-311.pyc +0 -0
  75. package/skills/grilling/__pycache__/socratic_tree.cpython-311.pyc +0 -0
  76. package/skills/research_cache/__pycache__/__init__.cpython-311.pyc +0 -0
  77. package/skills/research_cache/__pycache__/hasher.cpython-311.pyc +0 -0
  78. package/skills/swarm_config/SKILL.md +26 -0
  79. package/skills/swarm_config/__pycache__/__init__.cpython-311.pyc +0 -0
  80. package/skills/swarm_config/__pycache__/configure.cpython-311.pyc +0 -0
  81. package/skills/swarm_config/configure.py +40 -6
@@ -38,6 +38,7 @@ from skills.swarm_config.configure import ( # noqa: E402
38
38
  ConfigHashError,
39
39
  ConfigStaleError,
40
40
  ConfigValidationError,
41
+ _FALLBACK_DEFAULT_CONFIG,
41
42
  config_hash,
42
43
  heal_config,
43
44
  load_config,
@@ -54,6 +55,26 @@ def _write_config(base_dir: Path, payload: dict) -> Path:
54
55
  return cfg_file
55
56
 
56
57
 
58
+ class TestFallbackDrift(unittest.TestCase):
59
+ """Phase-03 R2: the standalone fallback literal tracks the canonical defaults.
60
+
61
+ Replaces the old comment-only "drift guard" (which named a test that never
62
+ existed): this is the real test. `_FALLBACK_DEFAULT_CONFIG` is the
63
+ standalone path of `DEFAULT_CONFIG`, so any key added to
64
+ `runner.schemas.CONFIG_DEFAULTS` without updating the literal fails here.
65
+ """
66
+
67
+ def test_fallback_literal_matches_canonical_defaults(self):
68
+ from runner.schemas import CONFIG_DEFAULTS
69
+
70
+ self.assertEqual(_FALLBACK_DEFAULT_CONFIG, CONFIG_DEFAULTS)
71
+
72
+ def test_fallback_literal_covers_every_schema_key(self):
73
+ from runner.schemas import CONFIG
74
+
75
+ self.assertEqual(set(_FALLBACK_DEFAULT_CONFIG), set(CONFIG["properties"]))
76
+
77
+
57
78
  class TestLegacyAgentPinMigration(unittest.TestCase):
58
79
  def test_legacy_pin_is_dropped_when_backend_is_auto(self):
59
80
  with tempfile.TemporaryDirectory() as tmp:
@@ -294,6 +294,17 @@
294
294
  "x-scope": "dispatch",
295
295
  "x-restart": "next-run",
296
296
  "description": "Default named opencode agent profile for all roles; per-role agents.<role>.opencode_agent wins."
297
+ },
298
+ "mcp_servers": {
299
+ "type": "object",
300
+ "default": {},
301
+ "x-label": "MCP Servers",
302
+ "x-scope": "dispatch",
303
+ "x-restart": "next-run",
304
+ "description": "Persisted toggle map for the plugin-controllable MCP server set (bundled `iumbtems` server plus research servers declared in the project OpenCode config). Keys are server names; values are booleans (true = enabled, false = disabled). Absent keys mean enabled. Applied via ctx.mcp.transform (`disabled` reconcile); the catalog file config/mcp-research-servers.json is never modified.",
305
+ "additionalProperties": {
306
+ "type": "boolean"
307
+ }
297
308
  }
298
309
  }
299
310
  }
@@ -124,6 +124,32 @@ prefix of **at least 8 hex characters**; conflicting spellings are rejected with
124
124
  canonical validation (the legacy-pin migration stays in memory until the
125
125
  invalid values are fixed).
126
126
 
127
+ ## 4. TUI Settings Surface (OpenCode V2)
128
+
129
+ On OpenCode V2 hosts the plugin ships a native settings surface — the recommended
130
+ path when you are already inside OpenCode:
131
+
132
+ - **`/swarm-config` wizard** — `ui.dialog.select/prompt/confirm`, one row per
133
+ canonical key with a provenance badge (`default` / `file` / `env-override`);
134
+ edits validate on save.
135
+ - **`iumbtems.swarm-settings` status panel** — a read-only panel opened from the
136
+ command palette / keymap showing the effective rows with a **next-run** badge;
137
+ it never writes.
138
+
139
+ Both read and write the same canonical `.research/config.json`, preferring the
140
+ server `iumbtems.settings` RPC (server-side validation + `expectedHash` guard) and
141
+ degrading to a direct-fs write (`plugins/opencode/config-io.js`) with a visible
142
+ toast when `client.rpc` is absent. Live refresh subscribes to the RPC `changed`
143
+ event; the 5s poll remains the floor.
144
+
145
+ The honest boundaries are unchanged from the CLI/MCP paths: values apply to the
146
+ **next** swarm run (the runner reads config at run start); per-role temperature
147
+ does **not** govern spawned agents (dated `[NEGATIVE_KNOWLEDGE]`, waiver W3);
148
+ out-of-range `IUMBTEMS_TEMPERATURE[_<ROLE>]` values are DISCARDED (fail-closed),
149
+ not clamped; secrets stay in the environment. See `docs/SYSTEM_ARCHITECTURE.md`
150
+ §6.7 for the full data flow, the `.research/.config.lock` protocol, the
151
+ `expectedHash` guard, and the `ctx.storage` mirror.
152
+
127
153
  ## 5. Known limitations (recorded by phase 01)
128
154
 
129
155
  - **Crash-safety scope (F9):** the atomic-write regression patches `os.replace`
@@ -88,8 +88,9 @@ except ImportError: # pragma: no cover - standalone skill copy
88
88
  _file_lock = _fallback_file_lock
89
89
 
90
90
 
91
- # Literal fallback for standalone runs; `test_config_schema.py` asserts it stays
92
- # byte-identical to `runner.schemas.CONFIG_DEFAULTS` (drift guard).
91
+ # Literal fallback for standalone runs (runner/ not importable). It must stay
92
+ # in sync with the canonical `runner.schemas.CONFIG_DEFAULTS`; the drift test
93
+ # `TestFallbackDrift` in `runner/tests/test_swarm_config.py` asserts equality.
93
94
  _FALLBACK_DEFAULT_CONFIG: Dict[str, Any] = {
94
95
  "search_engine": "duckduckgo",
95
96
  "max_iterations": 2,
@@ -124,6 +125,8 @@ _FALLBACK_DEFAULT_CONFIG: Dict[str, Any] = {
124
125
  },
125
126
  "opencode_auto": None, # None = enabled unless IUMBTEMS_OPENCODE_AUTO says no
126
127
  "opencode_agent": None, # None = inline the prompt, no --agent
128
+ # Persisted MCP-server toggle map (phase 03); mirrors CONFIG_DEFAULTS.
129
+ "mcp_servers": {},
127
130
  }
128
131
 
129
132
  DEFAULT_CONFIG: Dict[str, Any] = copy.deepcopy(
@@ -691,15 +694,38 @@ def _save_or_report(cfg: Dict[str, Any]) -> Optional[Path]:
691
694
  return None
692
695
 
693
696
 
697
+ def _legacy_pin_pending(base_dir: str = DEFAULT_RESEARCH_DIR) -> bool:
698
+ """Would the legacy-pin migration apply on the next save? (read-only)
699
+
700
+ R12/F2: the CLI read paths (`--show` / bare) must never write, so this
701
+ reports a pending migration without persisting it. Mirrors `heal_config`'s
702
+ decision — a legacy ``["claude", "-p"]`` pin is present AND the
703
+ would-be-persisted config passes canonical validation — but never writes.
704
+ """
705
+ try:
706
+ raw = _read_raw_config(get_config_path(base_dir))
707
+ if not isinstance(raw, dict):
708
+ return False
709
+ if not migrate_legacy_agent_backends(raw):
710
+ return False
711
+ return not validate_config(load_config(base_dir))
712
+ except Exception:
713
+ return False
714
+
715
+
694
716
  def main():
695
717
  cfg = load_config()
696
- if heal_config():
697
- print(
698
- "ℹ️ Migrated legacy ['claude', '-p'] agent backend pin → host-native default."
699
- )
700
718
  args = sys.argv[1:]
719
+ # R12/F2: compute the pending migration READ-ONLY. Heal only when an update
720
+ # is actually saved; a read (`--show` / bare) must never write.
721
+ pending_migration = _legacy_pin_pending()
701
722
 
702
723
  if not args or "--show" in args:
724
+ if pending_migration:
725
+ print(
726
+ "ℹ️ A legacy ['claude', '-p'] agent backend pin is present; it "
727
+ "will migrate to the host-native default on the next save."
728
+ )
703
729
  display_config(cfg)
704
730
  if not args:
705
731
  print("To edit settings, run:")
@@ -714,6 +740,10 @@ def main():
714
740
  cfg_path = _save_or_report(cfg)
715
741
  if cfg_path is None:
716
742
  raise SystemExit(1)
743
+ if pending_migration:
744
+ print(
745
+ "ℹ️ Migrated legacy ['claude', '-p'] agent backend pin → host-native default."
746
+ )
717
747
  print(f"✅ Configuration saved to {cfg_path}")
718
748
  display_config(cfg)
719
749
  return
@@ -723,6 +753,10 @@ def main():
723
753
  cfg_path = _save_or_report(cfg)
724
754
  if cfg_path is None:
725
755
  raise SystemExit(1)
756
+ if pending_migration:
757
+ print(
758
+ "ℹ️ Migrated legacy ['claude', '-p'] agent backend pin → host-native default."
759
+ )
726
760
  print(f"✅ Configuration updated and saved to {cfg_path}")
727
761
  display_config(cfg)
728
762