@heretek-ai/epistemic-swarm 0.7.13 ā 0.7.15
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 +6 -2
- package/package.json +2 -1
- package/plugins/factory/skills/factory/scripts/factory.py +68 -14
- package/plugins/opencode/index.js +21 -0
- package/plugins/socratic-grilling/skills/grilling/SKILL.md +14 -1
- package/plugins/socratic-grilling/skills/grilling/socratic_tree.py +88 -16
- 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/errors.py +51 -0
- package/runner/mcp_server.py +132 -8
- package/runner/preflight.py +157 -0
- package/runner/research_swarm.py +148 -4
- package/runner/schema_validate.py +93 -0
- package/runner/schemas.py +270 -0
- package/runner/state_machine.py +96 -10
- 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_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_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_contract_tooling.py +312 -0
- package/runner/tests/test_mcp_server.py +2 -0
- package/runner/tests/test_opencode_ux.py +4 -2
- package/schemas/alpha_dossier.schema.json +204 -0
- package/schemas/audit_report.schema.json +76 -0
- package/schemas/beta_dossier.schema.json +214 -0
- package/schemas/frontier.schema.json +61 -0
- package/schemas/manifest.schema.json +43 -0
- package/schemas/scope_manifest.schema.json +47 -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/scripts/check_docs.py +66 -0
- package/scripts/gen_schemas.py +69 -0
- package/skills/epistemic_search/scripts/__pycache__/search.cpython-311.pyc +0 -0
- package/skills/factory/scripts/factory.py +68 -14
- package/skills/grilling/SKILL.md +14 -1
- package/skills/grilling/__pycache__/__init__.cpython-311.pyc +0 -0
- package/skills/grilling/__pycache__/socratic_tree.cpython-311.pyc +0 -0
- package/skills/grilling/socratic_tree.py +88 -16
- 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/__pycache__/__init__.cpython-311.pyc +0 -0
- package/skills/swarm_config/__pycache__/configure.cpython-311.pyc +0 -0
|
@@ -11,10 +11,17 @@ import argparse
|
|
|
11
11
|
from pathlib import Path
|
|
12
12
|
from typing import Dict, List, Optional, Any
|
|
13
13
|
|
|
14
|
+
|
|
14
15
|
class DecisionNode:
|
|
15
|
-
def __init__(
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
node_id: str,
|
|
19
|
+
title: str,
|
|
20
|
+
question: str,
|
|
21
|
+
recommended: str,
|
|
22
|
+
options: Optional[List[str]] = None,
|
|
23
|
+
prerequisites: Optional[List[str]] = None,
|
|
24
|
+
):
|
|
18
25
|
self.node_id = node_id
|
|
19
26
|
self.title = title
|
|
20
27
|
self.question = question
|
|
@@ -34,18 +41,18 @@ class DecisionNode:
|
|
|
34
41
|
"recommended": self.recommended,
|
|
35
42
|
"options": self.options,
|
|
36
43
|
"prerequisites": self.prerequisites,
|
|
37
|
-
"settled_answer": self.settled_answer
|
|
44
|
+
"settled_answer": self.settled_answer,
|
|
38
45
|
}
|
|
39
46
|
|
|
40
47
|
@classmethod
|
|
41
|
-
def from_dict(cls, data: Dict[str, Any]) ->
|
|
48
|
+
def from_dict(cls, data: Dict[str, Any]) -> "DecisionNode":
|
|
42
49
|
node = cls(
|
|
43
50
|
node_id=data["node_id"],
|
|
44
51
|
title=data["title"],
|
|
45
52
|
question=data["question"],
|
|
46
53
|
recommended=data["recommended"],
|
|
47
54
|
options=data.get("options", []),
|
|
48
|
-
prerequisites=data.get("prerequisites", [])
|
|
55
|
+
prerequisites=data.get("prerequisites", []),
|
|
49
56
|
)
|
|
50
57
|
node.settled_answer = data.get("settled_answer")
|
|
51
58
|
return node
|
|
@@ -82,7 +89,9 @@ class DesignTree:
|
|
|
82
89
|
self.nodes[node_id].settled_answer = answer
|
|
83
90
|
|
|
84
91
|
def is_complete(self) -> bool:
|
|
85
|
-
return len(self.compute_frontier()) == 0 and all(
|
|
92
|
+
return len(self.compute_frontier()) == 0 and all(
|
|
93
|
+
n.is_settled() for n in self.nodes.values()
|
|
94
|
+
)
|
|
86
95
|
|
|
87
96
|
def export_frontier_json(self, output_path: Path):
|
|
88
97
|
safe_path = Path(os.path.realpath(str(output_path)))
|
|
@@ -93,13 +102,13 @@ class DesignTree:
|
|
|
93
102
|
"nodes": {k: v.to_dict() for k, v in self.nodes.items()},
|
|
94
103
|
"settled_constraints": {
|
|
95
104
|
k: v.settled_answer for k, v in self.nodes.items() if v.is_settled()
|
|
96
|
-
}
|
|
105
|
+
},
|
|
97
106
|
}
|
|
98
107
|
with open(safe_path, "w", encoding="utf-8") as f:
|
|
99
108
|
json.dump(data, f, indent=2)
|
|
100
109
|
|
|
101
110
|
@classmethod
|
|
102
|
-
def load_from_json(cls, file_path: Path) ->
|
|
111
|
+
def load_from_json(cls, file_path: Path) -> "DesignTree":
|
|
103
112
|
safe_path = Path(os.path.realpath(str(file_path)))
|
|
104
113
|
with open(safe_path, "r", encoding="utf-8") as f:
|
|
105
114
|
data = json.load(f)
|
|
@@ -111,12 +120,16 @@ class DesignTree:
|
|
|
111
120
|
|
|
112
121
|
def _display_frontier(tree: DesignTree, frontier: list) -> None:
|
|
113
122
|
print(f"\nšÆ Objective: {tree.objective}")
|
|
114
|
-
print(
|
|
123
|
+
print(
|
|
124
|
+
f"š Total Nodes: {len(tree.nodes)} | Settled: {sum(1 for n in tree.nodes.values() if n.is_settled())}"
|
|
125
|
+
)
|
|
115
126
|
if not frontier:
|
|
116
127
|
if tree.nodes and tree.is_complete():
|
|
117
128
|
print("ā
Frontier is EMPTY. All prerequisite branches are fully settled!")
|
|
118
129
|
else:
|
|
119
|
-
print(
|
|
130
|
+
print(
|
|
131
|
+
"ā¹ļø No active frontier nodes. Define new decision nodes to begin grilling."
|
|
132
|
+
)
|
|
120
133
|
else:
|
|
121
134
|
print(f"\nā” Current Active Frontier ({len(frontier)} questions ready):")
|
|
122
135
|
for idx, node in enumerate(frontier, 1):
|
|
@@ -126,11 +139,49 @@ def _display_frontier(tree: DesignTree, frontier: list) -> None:
|
|
|
126
139
|
|
|
127
140
|
|
|
128
141
|
def main():
|
|
129
|
-
parser = argparse.ArgumentParser(
|
|
142
|
+
parser = argparse.ArgumentParser(
|
|
143
|
+
description="Epistemic Swarm Socratic Decision Tree"
|
|
144
|
+
)
|
|
130
145
|
parser.add_argument("--objective", type=str, help="Research objective")
|
|
131
|
-
parser.add_argument(
|
|
132
|
-
|
|
133
|
-
|
|
146
|
+
parser.add_argument(
|
|
147
|
+
"--file",
|
|
148
|
+
type=str,
|
|
149
|
+
default=".research/frontier.json",
|
|
150
|
+
help="Path to frontier.json",
|
|
151
|
+
)
|
|
152
|
+
parser.add_argument(
|
|
153
|
+
"--show-frontier",
|
|
154
|
+
action="store_true",
|
|
155
|
+
help="Print the current decision frontier",
|
|
156
|
+
)
|
|
157
|
+
parser.add_argument(
|
|
158
|
+
"--settle",
|
|
159
|
+
nargs=2,
|
|
160
|
+
metavar=("NODE_ID", "ANSWER"),
|
|
161
|
+
help="Settle a decision node",
|
|
162
|
+
)
|
|
163
|
+
parser.add_argument(
|
|
164
|
+
"--add-node",
|
|
165
|
+
action="store_true",
|
|
166
|
+
help="Add a decision node (with --id/--question)",
|
|
167
|
+
)
|
|
168
|
+
parser.add_argument("--id", type=str, help="Node id (with --add-node)")
|
|
169
|
+
parser.add_argument("--question", type=str, help="Node question (with --add-node)")
|
|
170
|
+
parser.add_argument(
|
|
171
|
+
"--title", type=str, default="", help="Node title (defaults to --id)"
|
|
172
|
+
)
|
|
173
|
+
parser.add_argument(
|
|
174
|
+
"--recommended", type=str, default="", help="Recommended option"
|
|
175
|
+
)
|
|
176
|
+
parser.add_argument(
|
|
177
|
+
"--depends-on",
|
|
178
|
+
type=str,
|
|
179
|
+
default="",
|
|
180
|
+
help="Comma-separated prerequisite node ids",
|
|
181
|
+
)
|
|
182
|
+
parser.add_argument(
|
|
183
|
+
"--export", action="store_true", help="Write the frontier JSON and exit"
|
|
184
|
+
)
|
|
134
185
|
|
|
135
186
|
args = parser.parse_args()
|
|
136
187
|
frontier_path = Path(os.path.realpath(str(args.file)))
|
|
@@ -141,14 +192,35 @@ def main():
|
|
|
141
192
|
objective = args.objective or "Epistemic Swarm Research Objective"
|
|
142
193
|
tree = DesignTree(objective=objective)
|
|
143
194
|
|
|
195
|
+
if args.add_node:
|
|
196
|
+
if not args.id or not args.question:
|
|
197
|
+
parser.error("--add-node requires --id and --question")
|
|
198
|
+
prereqs = [p.strip() for p in (args.depends_on or "").split(",") if p.strip()]
|
|
199
|
+
tree.add_node(
|
|
200
|
+
DecisionNode(
|
|
201
|
+
node_id=args.id,
|
|
202
|
+
title=args.title or args.id,
|
|
203
|
+
question=args.question,
|
|
204
|
+
recommended=args.recommended or "",
|
|
205
|
+
options=[],
|
|
206
|
+
prerequisites=prereqs,
|
|
207
|
+
)
|
|
208
|
+
)
|
|
209
|
+
tree.export_frontier_json(frontier_path)
|
|
210
|
+
print(f"Added node {args.id} -> {frontier_path}")
|
|
211
|
+
|
|
144
212
|
if args.settle:
|
|
145
213
|
node_id, answer = args.settle
|
|
146
214
|
tree.settle_node(node_id, answer)
|
|
147
215
|
tree.export_frontier_json(frontier_path)
|
|
148
216
|
print(f"Settled {node_id} -> {answer}")
|
|
149
217
|
|
|
218
|
+
if args.export:
|
|
219
|
+
tree.export_frontier_json(frontier_path)
|
|
220
|
+
print(f"Exported frontier -> {frontier_path}")
|
|
221
|
+
|
|
150
222
|
frontier = tree.compute_frontier()
|
|
151
|
-
if args.show_frontier or not args.settle:
|
|
223
|
+
if args.show_frontier or not (args.settle or args.add_node or args.export):
|
|
152
224
|
_display_frontier(tree, frontier)
|
|
153
225
|
|
|
154
226
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|