@heretek-ai/epistemic-swarm 0.7.11 → 0.7.13
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/package.json +1 -1
- package/plugins/research-cache/skills/research_cache/hasher.py +56 -14
- package/prompts/agent_brainstormer.md +14 -0
- package/prompts/agent_darkharvest.md +20 -1
- 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__/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__/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__/state_machine.cpython-311.pyc +0 -0
- package/runner/auditor_engine.py +267 -80
- package/runner/darkharvest_claims.py +326 -0
- package/runner/refinement.py +74 -0
- package/runner/research_swarm.py +119 -24
- package/runner/retrieval_log.py +90 -0
- package/runner/state_machine.py +35 -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_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_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_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_darkharvest_audit.py +290 -0
- package/runner/tests/test_grounding.py +183 -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__/divergence_experiment.cpython-311.pyc +0 -0
- package/skills/epistemic_search/scripts/__pycache__/search.cpython-311.pyc +0 -0
- package/skills/epistemic_search/scripts/search.py +16 -0
- package/skills/epistemic_search/scripts/webcache.py +11 -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/research_cache/hasher.py +56 -14
- package/skills/swarm_config/__pycache__/__init__.cpython-311.pyc +0 -0
- package/skills/swarm_config/__pycache__/configure.cpython-311.pyc +0 -0
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.13",
|
|
4
4
|
"description": "IUMBTEMS (Epistemic Swarm) — 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": {
|
|
@@ -17,6 +17,20 @@ from typing import Dict, Any, Optional, Tuple
|
|
|
17
17
|
DEFAULT_RESEARCH_DIR = ".research"
|
|
18
18
|
BASE_DIR_HELP = "Base .research directory"
|
|
19
19
|
|
|
20
|
+
|
|
21
|
+
def _log_retrieval(base_dir, kind: str, **fields) -> None:
|
|
22
|
+
"""Best-effort retrieval telemetry (see runner/retrieval_log.py)."""
|
|
23
|
+
try:
|
|
24
|
+
root = Path(__file__).resolve().parents[2]
|
|
25
|
+
if str(root) not in sys.path:
|
|
26
|
+
sys.path.insert(0, str(root))
|
|
27
|
+
from runner.retrieval_log import log_event
|
|
28
|
+
|
|
29
|
+
log_event(base_dir, kind, **fields)
|
|
30
|
+
except Exception:
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
|
|
20
34
|
class SourceHasher:
|
|
21
35
|
def __init__(self, base_dir: Optional[Path] = None):
|
|
22
36
|
target = base_dir or Path(DEFAULT_RESEARCH_DIR)
|
|
@@ -30,8 +44,14 @@ class SourceHasher:
|
|
|
30
44
|
normalized = content.strip().encode("utf-8")
|
|
31
45
|
return hashlib.sha256(normalized).hexdigest()
|
|
32
46
|
|
|
33
|
-
def store_source(
|
|
34
|
-
|
|
47
|
+
def store_source(
|
|
48
|
+
self,
|
|
49
|
+
url: str,
|
|
50
|
+
content: str,
|
|
51
|
+
title: Optional[str] = None,
|
|
52
|
+
tier: str = "WEB_DOCUMENT",
|
|
53
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
54
|
+
) -> str:
|
|
35
55
|
"""Store content and metadata content-addressed by SHA-256."""
|
|
36
56
|
content_hash = self.compute_sha256(content)
|
|
37
57
|
md_path = self.sources_dir / f"{content_hash}.md"
|
|
@@ -50,7 +70,7 @@ class SourceHasher:
|
|
|
50
70
|
"cached_at": datetime.now(timezone.utc).isoformat(),
|
|
51
71
|
"byte_size": len(content.encode("utf-8")),
|
|
52
72
|
"char_count": len(content),
|
|
53
|
-
"custom_metadata": metadata or {}
|
|
73
|
+
"custom_metadata": metadata or {},
|
|
54
74
|
}
|
|
55
75
|
with open(json_path, "w", encoding="utf-8") as f:
|
|
56
76
|
json.dump(meta, f, indent=2)
|
|
@@ -84,7 +104,9 @@ class SourceHasher:
|
|
|
84
104
|
"""
|
|
85
105
|
if not re.match(r"^[a-fA-F0-9]+$", hash_prefix):
|
|
86
106
|
return None
|
|
87
|
-
exact_path = Path(
|
|
107
|
+
exact_path = Path(
|
|
108
|
+
os.path.realpath(str(self.sources_dir / f"{hash_prefix}{extension}"))
|
|
109
|
+
)
|
|
88
110
|
if exact_path.parent != self.sources_dir:
|
|
89
111
|
return None
|
|
90
112
|
if exact_path.exists():
|
|
@@ -102,12 +124,16 @@ class SourceHasher:
|
|
|
102
124
|
def normalize_text_for_search(text: str) -> str:
|
|
103
125
|
"""Collapse whitespace and normalize typography for substring matching."""
|
|
104
126
|
# Replace smart quotes and dashes
|
|
105
|
-
text =
|
|
127
|
+
text = (
|
|
128
|
+
text.replace("“", '"').replace("”", '"').replace("‘", "'").replace("’", "'")
|
|
129
|
+
)
|
|
106
130
|
text = text.replace("—", "-").replace("–", "-")
|
|
107
131
|
# Collapse all whitespace to single spaces
|
|
108
132
|
return re.sub(r"\s+", " ", text).strip().lower()
|
|
109
133
|
|
|
110
|
-
def verify_quote(
|
|
134
|
+
def verify_quote(
|
|
135
|
+
self, content_hash: str, quote: str
|
|
136
|
+
) -> Tuple[bool, float, Optional[str]]:
|
|
111
137
|
"""
|
|
112
138
|
Verifies whether quote exists in cached document.
|
|
113
139
|
Returns: (is_verified, confidence_score, context_match)
|
|
@@ -136,7 +162,7 @@ class SourceHasher:
|
|
|
136
162
|
best_score = 0.0
|
|
137
163
|
|
|
138
164
|
for i in range(max(1, len(source_words) - window_size + 1)):
|
|
139
|
-
window = source_words[i:i + window_size]
|
|
165
|
+
window = source_words[i : i + window_size]
|
|
140
166
|
matches = sum(1 for w1, w2 in zip(quote_words, window) if w1 == w2)
|
|
141
167
|
score = matches / window_size
|
|
142
168
|
if score > best_score:
|
|
@@ -147,11 +173,17 @@ class SourceHasher:
|
|
|
147
173
|
if best_score >= 0.88:
|
|
148
174
|
return True, best_score, f"High-confidence fuzzy match ({best_score:.2f})."
|
|
149
175
|
|
|
150
|
-
return
|
|
176
|
+
return (
|
|
177
|
+
False,
|
|
178
|
+
best_score,
|
|
179
|
+
f"Verification failed. Highest word overlap: {best_score:.2f}.",
|
|
180
|
+
)
|
|
151
181
|
|
|
152
182
|
|
|
153
183
|
def main():
|
|
154
|
-
parser = argparse.ArgumentParser(
|
|
184
|
+
parser = argparse.ArgumentParser(
|
|
185
|
+
description="Epistemic Swarm Content Hasher & Quote Verifier"
|
|
186
|
+
)
|
|
155
187
|
subparsers = parser.add_subparsers(dest="command")
|
|
156
188
|
|
|
157
189
|
# Cache command
|
|
@@ -166,7 +198,9 @@ def main():
|
|
|
166
198
|
verify_parser = subparsers.add_parser("verify", help="Verify a verbatim quote")
|
|
167
199
|
verify_parser.add_argument("--hash", required=True, help="Document SHA-256 hash")
|
|
168
200
|
verify_parser.add_argument("--quote", required=True, help="Verbatim quote to check")
|
|
169
|
-
verify_parser.add_argument(
|
|
201
|
+
verify_parser.add_argument(
|
|
202
|
+
"--dir", default=DEFAULT_RESEARCH_DIR, help=BASE_DIR_HELP
|
|
203
|
+
)
|
|
170
204
|
|
|
171
205
|
# List command
|
|
172
206
|
list_parser = subparsers.add_parser("list", help="List cached sources")
|
|
@@ -182,18 +216,26 @@ def main():
|
|
|
182
216
|
if not sys.stdin.isatty():
|
|
183
217
|
content = sys.stdin.read()
|
|
184
218
|
else:
|
|
185
|
-
print(
|
|
219
|
+
print(
|
|
220
|
+
"Error: No content provided via --content or stdin.",
|
|
221
|
+
file=sys.stderr,
|
|
222
|
+
)
|
|
186
223
|
sys.exit(1)
|
|
187
|
-
h = hasher.store_source(
|
|
224
|
+
h = hasher.store_source(
|
|
225
|
+
url=args.url, content=content, title=args.title, tier=args.tier
|
|
226
|
+
)
|
|
188
227
|
print(f"[CACHED] {h} -> {args.title} ({args.url})")
|
|
228
|
+
_log_retrieval(hasher.base_dir, "cache", url=args.url, hash=h, tool="hasher")
|
|
189
229
|
|
|
190
230
|
elif args.command == "verify":
|
|
191
|
-
verified, conf, msg = hasher.verify_quote(
|
|
231
|
+
verified, conf, msg = hasher.verify_quote(
|
|
232
|
+
content_hash=args.hash, quote=args.quote
|
|
233
|
+
)
|
|
192
234
|
result = {
|
|
193
235
|
"hash": args.hash,
|
|
194
236
|
"verified": verified,
|
|
195
237
|
"confidence": conf,
|
|
196
|
-
"message": msg
|
|
238
|
+
"message": msg,
|
|
197
239
|
}
|
|
198
240
|
print(json.dumps(result, indent=2))
|
|
199
241
|
sys.exit(0 if verified else 1)
|
|
@@ -26,6 +26,20 @@ context < 40%, use shallow mode (README + top-level tree only) and say so.
|
|
|
26
26
|
- Open loops: TODOs, failing tests, stale branches.
|
|
27
27
|
3. NEVER invent file contents. If a file was not ingested, mark the claim
|
|
28
28
|
`[HYPOTHESIS: <how to check>]`, never `[VERIFIED]`.
|
|
29
|
+
4. **External grounding** (mandatory when the objective implies external facts,
|
|
30
|
+
benchmarks, or prior art): discover with the zero-key search skill and cache
|
|
31
|
+
every source before citing it:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
python3 skills/epistemic_search/scripts/search.py "<query>"
|
|
35
|
+
python3 skills/research_cache/hasher.py cache --url "<URL>" --content "$(cat fetched.md)" --title "<TITLE>"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Cite a cached source as `[VERIFIED: <sha256>]` **with an exact
|
|
39
|
+
`verbatim_quote`**; anything not retrieved stays `[HYPOTHESIS: <test>]`. A run
|
|
40
|
+
that never searches yields zero cached sources and will be flagged
|
|
41
|
+
`WARNING_LOW_GROUNDING` — that is only acceptable when the objective is purely
|
|
42
|
+
internal to the workspace.
|
|
29
43
|
|
|
30
44
|
## 2. DIALECTICAL DIVERGENCE (mandatory, in order)
|
|
31
45
|
|
|
@@ -33,6 +33,17 @@ partial per capability), benchmark/API quotes, and per-feature harvest
|
|
|
33
33
|
proposals. Every cell needs `[VERIFIED: <hash>]` from
|
|
34
34
|
`.research/sources/<sha256>.md` or `file://<path>#L<start>-L<end>`.
|
|
35
35
|
|
|
36
|
+
Discover and cache every cited source before you cite it (zero-key, no API keys):
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
python3 skills/epistemic_search/scripts/search.py "<query>"
|
|
40
|
+
python3 skills/research_cache/hasher.py cache --url "<URL>" --content "$(cat fetched.md)" --title "<TITLE>"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Confirm a repository actually exists (`owner/repo`) before citing it. A run that
|
|
44
|
+
never searches caches zero sources and is flagged `WARNING_LOW_GROUNDING` — the
|
|
45
|
+
runner prints `retrieval: N queries, M results, K cached` as evidence either way.
|
|
46
|
+
|
|
36
47
|
### Beta — Red Team
|
|
37
48
|
License gate (LICENSE file + package metadata → SPDX), transitive weight,
|
|
38
49
|
CVE/takeover notes, staleness (`⚠️ STALE` when >12mo or solo-maintainer),
|
|
@@ -51,7 +62,9 @@ AND what we lack). Gates are warn-only: badge inline, never auto-skip.
|
|
|
51
62
|
## 4. OUTPUT SPECIFICATION
|
|
52
63
|
|
|
53
64
|
Per scope write `alpha_dossier.json` / `beta_dossier.json` with
|
|
54
|
-
`candidate_repositories[]` entries
|
|
65
|
+
`candidate_repositories[]` entries. Every entry MUST carry `source_hash` **and**
|
|
66
|
+
`verbatim_quote` (an exact substring of the cached `.research/sources/<hash>.md`);
|
|
67
|
+
entries without both are rejected as unverified by the audit.
|
|
55
68
|
|
|
56
69
|
```json
|
|
57
70
|
{
|
|
@@ -59,6 +72,7 @@ Per scope write `alpha_dossier.json` / `beta_dossier.json` with
|
|
|
59
72
|
"name": "owner/repo",
|
|
60
73
|
"url": "https://github.com/owner/repo",
|
|
61
74
|
"source_hash": "<sha256>",
|
|
75
|
+
"verbatim_quote": "<exact substring of the cached source>",
|
|
62
76
|
"license": "Apache-2.0",
|
|
63
77
|
"license_risk": "SAFE | COPYLEFT_WARNING | PROHIBITIVE",
|
|
64
78
|
"harvest_policy": "depend-or-vendor | clean-room-rebuild-only",
|
|
@@ -89,3 +103,8 @@ candidates.
|
|
|
89
103
|
3. No unverified harvest verdicts. Metadata ranks; only VERIFIED harvests.
|
|
90
104
|
4. No unbounded expansion past `--max-repos` or per-repo caps without user
|
|
91
105
|
confirmation. Firecrawl missing → gap note, never abort.
|
|
106
|
+
5. **Do NOT self-report audit results.** Never emit `epistemic_audit`,
|
|
107
|
+
`confidence`, `verified_*`, `unverified_*`, `mean_epistemic_score`, or any
|
|
108
|
+
`*.verified` / `*.total_sources` field. The runner computes verification from
|
|
109
|
+
cached witnesses; agent-declared counts are ignored (renamed to
|
|
110
|
+
`self_reported_*`) and only mislead a human reader.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|