@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.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +23 -2
- package/package.json +1 -1
- package/plugins/antigravity/plugin.json +1 -1
- package/plugins/antigravity/rules/AGENTS.md +5 -3
- package/plugins/opencode/config-io.js +55 -12
- package/plugins/opencode/index.js +611 -0
- package/plugins/opencode/tui.js +278 -6
- package/runner/__pycache__/__init__.cpython-311.pyc +0 -0
- package/runner/__pycache__/auctioneer.cpython-311.pyc +0 -0
- package/runner/__pycache__/auditor_engine.cpython-311.pyc +0 -0
- package/runner/__pycache__/claim_store.cpython-311.pyc +0 -0
- package/runner/__pycache__/claim_witness.cpython-311.pyc +0 -0
- package/runner/__pycache__/darkharvest_claims.cpython-311.pyc +0 -0
- package/runner/__pycache__/errors.cpython-311.pyc +0 -0
- package/runner/__pycache__/living_dossiers.cpython-311.pyc +0 -0
- package/runner/__pycache__/mcp_protocol.cpython-311.pyc +0 -0
- package/runner/__pycache__/mcp_server.cpython-311.pyc +0 -0
- package/runner/__pycache__/path_safety.cpython-311.pyc +0 -0
- package/runner/__pycache__/pcrb.cpython-311.pyc +0 -0
- package/runner/__pycache__/pcrb_verify.cpython-311.pyc +0 -0
- package/runner/__pycache__/preflight.cpython-311.pyc +0 -0
- package/runner/__pycache__/refinement.cpython-311.pyc +0 -0
- package/runner/__pycache__/research_swarm.cpython-311.pyc +0 -0
- package/runner/__pycache__/retrieval_log.cpython-311.pyc +0 -0
- package/runner/__pycache__/schema_validate.cpython-311.pyc +0 -0
- package/runner/__pycache__/schemas.cpython-311.pyc +0 -0
- package/runner/__pycache__/state_machine.cpython-311.pyc +0 -0
- package/runner/mcp_server.py +81 -10
- package/runner/research_swarm.py +12 -2
- package/runner/schemas.py +18 -0
- package/runner/tests/__pycache__/test_antigravity_plugin.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_auction_order.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_backends.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_bet1_spike.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_claim_store.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_claim_witness.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_claude_plugin.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_config_schema.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_contract_tooling.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_darkharvest_audit.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_domain_packs.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_dossier_contract.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_factory.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_fleet_seam.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_frontier_concurrency.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_frontier_mirror_standalone.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_grounding.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_living_dossiers.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_manifest_concurrency.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_mcp_server.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_opencode_ux.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_opencode_v2_registrars.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_pcrb.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_refinement.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_search_anomaly.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_search_provider.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_search_provider_plugin.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_swarm.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_swarm_config.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_sweep_regressions.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_webcache.cpython-311.pyc +0 -0
- package/runner/tests/test_config_schema.py +106 -0
- package/runner/tests/test_opencode_ux.py +462 -7
- package/runner/tests/test_opencode_v2_registrars.py +1112 -3
- package/runner/tests/test_swarm_config.py +21 -0
- package/schemas/config.schema.json +11 -0
- package/scripts/__pycache__/bet1_advisory_spike.cpython-311.pyc +0 -0
- package/scripts/__pycache__/build_adapters.cpython-311.pyc +0 -0
- package/scripts/__pycache__/check_docs.cpython-311.pyc +0 -0
- package/scripts/__pycache__/divergence_experiment.cpython-311.pyc +0 -0
- package/scripts/__pycache__/gen_schemas.cpython-311.pyc +0 -0
- package/skills/epistemic_search/scripts/__pycache__/search.cpython-311.pyc +0 -0
- package/skills/grilling/__pycache__/__init__.cpython-311.pyc +0 -0
- package/skills/grilling/__pycache__/socratic_tree.cpython-311.pyc +0 -0
- package/skills/research_cache/__pycache__/__init__.cpython-311.pyc +0 -0
- package/skills/research_cache/__pycache__/hasher.cpython-311.pyc +0 -0
- package/skills/swarm_config/SKILL.md +26 -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 +40 -6
package/README.md
CHANGED
|
@@ -157,7 +157,7 @@ Related environment variables:
|
|
|
157
157
|
|
|
158
158
|
Spawned agents inherit `PWD` set to their working directory, so harnesses that resolve their project root from `$PWD` (OpenCode) land in the same tree the runner reads from.
|
|
159
159
|
|
|
160
|
-
> **Legacy config migration:** configs written before 0.7.6 could pin `agents.<role>.backend = ["claude", "-p"]`, which silently overrode the host-native default. That pin is now migrated to `null` on load (only when the top-level `backend` is not an explicit `"claude"`), and the migration is persisted
|
|
160
|
+
> **Legacy config migration:** configs written before 0.7.6 could pin `agents.<role>.backend = ["claude", "-p"]`, which silently overrode the host-native default. That pin is now migrated to `null` on load (only when the top-level `backend` is not an explicit `"claude"`), and the migration is persisted on the next config **write** (a read / `--show` never heals). To deliberately keep Claude on an OpenCode host, set `"backend": "claude"`.
|
|
161
161
|
|
|
162
162
|
---
|
|
163
163
|
|
|
@@ -265,6 +265,27 @@ Nine canonical skills live in `skills/*/SKILL.md`. Each maps to a slash command
|
|
|
265
265
|
|
|
266
266
|
---
|
|
267
267
|
|
|
268
|
+
## ⚙️ Settings Surface (`/swarm-config`)
|
|
269
|
+
|
|
270
|
+
The settings surface is the recommended way to tune the harness from inside OpenCode V2. It has two parts:
|
|
271
|
+
|
|
272
|
+
- **`/swarm-config` wizard** — a native dialog wizard (`ui.dialog.select/prompt/confirm`) showing every canonical key with a provenance badge (`default` / `file` / `env-override`), one editable row at a time, validated and written atomically on save.
|
|
273
|
+
- **Status panel** — a read-only panel opened from the command palette / keymap (`iumbtems.swarm-settings`) rendering the effective rows with a **next-run** badge. It never writes.
|
|
274
|
+
|
|
275
|
+
The canonical config it edits is **`.research/config.json`** — the TUI resolves `.research` from the OpenCode host root; `IUMBTEMS_PROJECT_DIR` / `--dir` / `base_dir` select the workspace for the CLI, MCP, and runner surfaces. Configurable values include the search engine, depth (`max_iterations`), operating `mode`, `backend`, per-role (`agents.*`) backend/model, `license_whitelist`, the cache / TTL / search-timeout knobs, `searxng_url`, `verify.min_fuzzy_confidence`, the persistence `mcp_servers` toggle map, `allocation`, `domain_pack`, and the deprecated display-only `output_dir`. (`divergence_threshold` is advisory: recorded, never gating a verdict.)
|
|
276
|
+
|
|
277
|
+
**Honest boundaries**
|
|
278
|
+
|
|
279
|
+
- **Values apply to the NEXT swarm run.** The Python runner reads `.research/config.json` once at run start, so a save never hot-swaps a running swarm — the wizard and panel both say "applies to the next swarm run".
|
|
280
|
+
- **Per-role temperature does not govern spawned agents.** The OpenCode session `context` hook honors `IUMBTEMS_TEMPERATURE[_<ROLE>]` for sessions running inside OpenCode, but there is **no verified path** that sets per-role temperature for spawned swarm agents — that leg is recorded `[NEGATIVE_KNOWLEDGE]` (S3, dated 2026-09-29; waiver W3). The UI deliberately makes no temperature claim.
|
|
281
|
+
- **No secrets in config.** API keys stay in the environment (`FIRECRAWL_API_KEY`, …). The surface only reports whether an env override is set for the keys it models; it never renders an env value, and it does not probe engine availability.
|
|
282
|
+
|
|
283
|
+
Writes prefer the plugin's `iumbtems.settings` RPC (server-side validation + an `expectedHash` lost-update guard; the RPC surfaces a `conflict` error type, and Python's code is `CONFLICTING_EXPECTED_HASH`) and degrade to a direct-fs write with a visible toast when `client.rpc` is absent; `.research/config.json` stays the single source of truth. See [docs/SYSTEM_ARCHITECTURE.md](docs/SYSTEM_ARCHITECTURE.md) §6.7 for the full data flow, the atomic-write + lock protocol, and the `ctx.storage` mirror.
|
|
284
|
+
|
|
285
|
+
*Reviewed settings-surface patterns from Gemini CLI, Codex, Goose, Aider, Cline, OpenCode, and Crush (docs-only) informed this design; no code was copied.*
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
268
289
|
## 🗂️ Workspace & Evidence Model
|
|
269
290
|
|
|
270
291
|
All state lives in a local `.research/` directory (resolved from `IUMBTEMS_PROJECT_DIR` when set, else the process cwd):
|
|
@@ -366,7 +387,7 @@ The package is distributed on npm as `@heretek-ai/epistemic-swarm` using [npm Tr
|
|
|
366
387
|
|
|
367
388
|
**Release flow** (see [AGENTS.md](AGENTS.md#releases)):
|
|
368
389
|
|
|
369
|
-
1. Bump `package.json`
|
|
390
|
+
1. Bump the **four enforced manifests** in lockstep: `package.json`, `package-lock.json`, `.claude-plugin/plugin.json`, and `plugins/antigravity/plugin.json` (`python3 scripts/build_adapters.py --check` guards the AntiGravity one).
|
|
370
391
|
2. Commit and push to `main`.
|
|
371
392
|
3. `gh release create vX.Y.Z` — the `Publish to npm` workflow
|
|
372
393
|
(`.github/workflows/publish.yml`) runs on `release: published`, executes the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heretek-ai/epistemic-swarm",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.21",
|
|
4
4
|
"description": "IUMBTEMS (Epistemic Swarm) \u2014 High-Integrity Dialectic Research Agent Harness for Claude Code, OpenCode V2, Pi (pi.dev), OMP (oh-my-pi), Gemini CLI, Codex CLI, and AntiGravity",
|
|
5
5
|
"main": "bin/cli.js",
|
|
6
6
|
"bin": {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://antigravity.google/schemas/v1/plugin.json",
|
|
3
3
|
"name": "epistemic-swarm",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.21",
|
|
5
5
|
"description": "IUMBTEMS (Epistemic Swarm) \u2014 High-Integrity Dialectic Research, Architecture Auditing, Competitor Teardowns, and Socratic Planning for Antigravity.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Heretek AI",
|
|
@@ -109,9 +109,11 @@ or `[NEGATIVE_KNOWLEDGE: <query>]`. Never present parametric recall as verified.
|
|
|
109
109
|
effect only after release + reinstall.
|
|
110
110
|
|
|
111
111
|
## Releases
|
|
112
|
-
- Bump
|
|
113
|
-
|
|
114
|
-
|
|
112
|
+
- Bump the **four enforced manifests** in lockstep — `package.json`,
|
|
113
|
+
`package-lock.json`, `.claude-plugin/plugin.json`, and
|
|
114
|
+
`plugins/antigravity/plugin.json` (0.7.5 shipped a stale plugin manifest and
|
|
115
|
+
v0.7.18 missed the AntiGravity manifest, failing `Validate All Harnesses` +
|
|
116
|
+
`Publish to npm` twice). Then commit, push to `main`, then
|
|
115
117
|
`gh release create vX.Y.Z`. The `Publish to npm` workflow (OIDC trusted
|
|
116
118
|
publishing) runs on release-published. Verify with
|
|
117
119
|
`curl https://registry.npmjs.org/@heretek-ai%2Fepistemic-swarm`
|
|
@@ -429,6 +429,7 @@ export const FALLBACK_DEFAULTS = {
|
|
|
429
429
|
},
|
|
430
430
|
opencode_auto: null,
|
|
431
431
|
opencode_agent: null,
|
|
432
|
+
mcp_servers: {},
|
|
432
433
|
};
|
|
433
434
|
|
|
434
435
|
/** Effective defaults, derived from the schema `default` keywords. */
|
|
@@ -589,6 +590,58 @@ export function isConfigMalformed(baseDir = DEFAULT_RESEARCH_DIR) {
|
|
|
589
590
|
}
|
|
590
591
|
}
|
|
591
592
|
|
|
593
|
+
/**
|
|
594
|
+
* Single-read snapshot of the config file (phase-03 R5): the raw bytes are
|
|
595
|
+
* read EXACTLY ONCE; `hash` is computed over those bytes and `raw` is parsed
|
|
596
|
+
* from those bytes, so a config parsed from one era can never pair with a
|
|
597
|
+
* hash of another. `malformed` is true when bytes exist but are not a JSON
|
|
598
|
+
* object. Never throws, never writes, never creates directories.
|
|
599
|
+
*/
|
|
600
|
+
export function readConfigSnapshot(baseDir = DEFAULT_RESEARCH_DIR) {
|
|
601
|
+
try {
|
|
602
|
+
const bytes = readBytes(getConfigPath(baseDir));
|
|
603
|
+
if (!bytes) return { hash: null, raw: null, malformed: false };
|
|
604
|
+
let hash = null;
|
|
605
|
+
try {
|
|
606
|
+
hash = createHash('sha256').update(bytes).digest('hex');
|
|
607
|
+
} catch {
|
|
608
|
+
hash = null;
|
|
609
|
+
}
|
|
610
|
+
const raw = parseJsonObject(bytes);
|
|
611
|
+
return { hash, raw, malformed: raw === null };
|
|
612
|
+
} catch {
|
|
613
|
+
return { hash: null, raw: null, malformed: false };
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
/**
|
|
618
|
+
* Effective config merged over defaults from an already-parsed raw object —
|
|
619
|
+
* the no-reread half of `loadConfig` (identical merge, migration, and
|
|
620
|
+
* fallback semantics; the caller owns the bytes). Never throws.
|
|
621
|
+
*/
|
|
622
|
+
export function loadConfigFromRaw(raw) {
|
|
623
|
+
try {
|
|
624
|
+
const base = configDefaults();
|
|
625
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return base;
|
|
626
|
+
const merged = { ...base, ...deepCopy(raw) };
|
|
627
|
+
merged.agents = mergeAgents(base.agents, raw.agents);
|
|
628
|
+
if (
|
|
629
|
+
raw.verify && typeof raw.verify === 'object' && !Array.isArray(raw.verify) &&
|
|
630
|
+
base.verify && typeof base.verify === 'object' && !Array.isArray(base.verify)
|
|
631
|
+
) {
|
|
632
|
+
merged.verify = { ...base.verify, ...deepCopy(raw.verify) };
|
|
633
|
+
}
|
|
634
|
+
migrateLegacyAgentBackends(merged);
|
|
635
|
+
return merged;
|
|
636
|
+
} catch {
|
|
637
|
+
try {
|
|
638
|
+
return deepCopy(FALLBACK_DEFAULTS);
|
|
639
|
+
} catch {
|
|
640
|
+
return {};
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
|
|
592
645
|
/**
|
|
593
646
|
* Load config merged over defaults. Pure — never writes. Applies the
|
|
594
647
|
* legacy-pin migration in memory; unknown keys are preserved verbatim.
|
|
@@ -596,7 +649,6 @@ export function isConfigMalformed(baseDir = DEFAULT_RESEARCH_DIR) {
|
|
|
596
649
|
*/
|
|
597
650
|
export function loadConfig(baseDir = DEFAULT_RESEARCH_DIR) {
|
|
598
651
|
try {
|
|
599
|
-
const base = configDefaults();
|
|
600
652
|
const raw = readRawConfig(baseDir);
|
|
601
653
|
if (!raw) {
|
|
602
654
|
if (isConfigMalformed(baseDir)) {
|
|
@@ -609,18 +661,9 @@ export function loadConfig(baseDir = DEFAULT_RESEARCH_DIR) {
|
|
|
609
661
|
/* logging must never throw */
|
|
610
662
|
}
|
|
611
663
|
}
|
|
612
|
-
return
|
|
664
|
+
return configDefaults();
|
|
613
665
|
}
|
|
614
|
-
|
|
615
|
-
merged.agents = mergeAgents(base.agents, raw.agents);
|
|
616
|
-
if (
|
|
617
|
-
raw.verify && typeof raw.verify === 'object' && !Array.isArray(raw.verify) &&
|
|
618
|
-
base.verify && typeof base.verify === 'object' && !Array.isArray(base.verify)
|
|
619
|
-
) {
|
|
620
|
-
merged.verify = { ...base.verify, ...deepCopy(raw.verify) };
|
|
621
|
-
}
|
|
622
|
-
migrateLegacyAgentBackends(merged);
|
|
623
|
-
return merged;
|
|
666
|
+
return loadConfigFromRaw(raw);
|
|
624
667
|
} catch {
|
|
625
668
|
try {
|
|
626
669
|
return deepCopy(FALLBACK_DEFAULTS);
|