@dzhechkov/skills-idea2prd 0.1.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.
- package/LICENSE +21 -0
- package/README.md +71 -0
- package/bin/cli.js +5 -0
- package/package.json +49 -0
- package/sources.json +25 -0
- package/src/cli.js +108 -0
- package/src/commands/doctor.js +340 -0
- package/src/commands/init.js +168 -0
- package/src/commands/list.js +146 -0
- package/src/commands/remove.js +182 -0
- package/src/commands/update.js +170 -0
- package/src/utils.js +154 -0
- package/templates/.claude/commands/idea2prd-manual.md +35 -0
- package/templates/.claude/skills/explore/SKILL.md +218 -0
- package/templates/.claude/skills/explore/references/questioning-techniques.md +151 -0
- package/templates/.claude/skills/explore/references/task-brief-templates.md +355 -0
- package/templates/.claude/skills/goap-research-ed25519/SKILL.md +418 -0
- package/templates/.claude/skills/goap-research-ed25519/references/ed25519-verification.md +658 -0
- package/templates/.claude/skills/goap-research-ed25519/references/research-actions.md +544 -0
- package/templates/.claude/skills/goap-research-ed25519/references/source-evaluation.md +560 -0
- package/templates/.claude/skills/goap-research-ed25519/scripts/ed25519_verifier.py +662 -0
- package/templates/.claude/skills/goap-research-ed25519/scripts/goap_planner.py +720 -0
- package/templates/.claude/skills/idea2prd-manual/SKILL.md +695 -0
- package/templates/.claude/skills/idea2prd-manual/references/adr-catalog.md +288 -0
- package/templates/.claude/skills/idea2prd-manual/references/c4-model.md +277 -0
- package/templates/.claude/skills/idea2prd-manual/references/completion-checklist-template.md +446 -0
- package/templates/.claude/skills/idea2prd-manual/references/ddd-patterns.md +261 -0
- package/templates/.claude/skills/idea2prd-manual/references/fitness-functions-catalog.md +414 -0
- package/templates/.claude/skills/idea2prd-manual/references/pseudocode-style.md +404 -0
- package/templates/.claude/skills/idea2prd-manual/scripts/ai_context_builder.py +491 -0
- package/templates/.claude/skills/idea2prd-manual/scripts/c4_generator.py +311 -0
- package/templates/.claude/skills/idea2prd-manual/scripts/fitness_validator.py +451 -0
- package/templates/.claude/skills/idea2prd-manual/scripts/pseudocode_generator.py +430 -0
- package/templates/.claude/skills/problem-solver-enhanced/SKILL.md +565 -0
|
@@ -0,0 +1,720 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
GOAP Research Planner with Ed25519 Verification
|
|
4
|
+
|
|
5
|
+
Enhanced Goal-Oriented Action Planning for research tasks with
|
|
6
|
+
cryptographic verification support for anti-hallucination protection.
|
|
7
|
+
|
|
8
|
+
Features:
|
|
9
|
+
- A* search for optimal research paths
|
|
10
|
+
- Ed25519 signature verification integration
|
|
11
|
+
- Verification penalty in cost function
|
|
12
|
+
- Citation chain management
|
|
13
|
+
- Trusted issuer whitelist support
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import heapq
|
|
17
|
+
import json
|
|
18
|
+
import hashlib
|
|
19
|
+
from dataclasses import dataclass, field, asdict
|
|
20
|
+
from typing import Dict, Set, List, Optional, Tuple, Any
|
|
21
|
+
from datetime import datetime
|
|
22
|
+
from enum import Enum
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class VerificationMode(Enum):
|
|
26
|
+
"""Research verification modes with different thresholds."""
|
|
27
|
+
DEVELOPMENT = 0.75
|
|
28
|
+
MODERATE = 0.85
|
|
29
|
+
STRICT = 0.95
|
|
30
|
+
PARANOID = 0.99
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@dataclass
|
|
34
|
+
class ResearchAction:
|
|
35
|
+
"""Represents a research action with preconditions, effects, and verification."""
|
|
36
|
+
name: str
|
|
37
|
+
preconditions: Set[str]
|
|
38
|
+
effects: Set[str]
|
|
39
|
+
cost: int
|
|
40
|
+
description: str = ""
|
|
41
|
+
requires_verification: bool = False
|
|
42
|
+
verification_type: Optional[str] = None # 'signature', 'chain', 'multi-sig'
|
|
43
|
+
|
|
44
|
+
def is_applicable(self, state: Set[str]) -> bool:
|
|
45
|
+
"""Check if action can be executed in current state."""
|
|
46
|
+
return self.preconditions.issubset(state)
|
|
47
|
+
|
|
48
|
+
def apply(self, state: Set[str]) -> Set[str]:
|
|
49
|
+
"""Apply action to state and return new state."""
|
|
50
|
+
return state.union(self.effects)
|
|
51
|
+
|
|
52
|
+
def get_total_cost(self, verification_enabled: bool = True) -> int:
|
|
53
|
+
"""Get total cost including verification overhead."""
|
|
54
|
+
if verification_enabled and self.requires_verification:
|
|
55
|
+
return self.cost + 1 # Verification overhead
|
|
56
|
+
return self.cost
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@dataclass(order=True)
|
|
60
|
+
class PlanNode:
|
|
61
|
+
"""Node in the A* search tree with verification tracking."""
|
|
62
|
+
f_cost: float
|
|
63
|
+
g_cost: float = field(compare=False)
|
|
64
|
+
state: Set[str] = field(compare=False)
|
|
65
|
+
actions: List[str] = field(compare=False)
|
|
66
|
+
unsigned_claims: int = field(compare=False, default=0)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@dataclass
|
|
70
|
+
class VerificationResult:
|
|
71
|
+
"""Result of a verification operation."""
|
|
72
|
+
verified: bool
|
|
73
|
+
confidence: float
|
|
74
|
+
source: str
|
|
75
|
+
timestamp: str
|
|
76
|
+
signature: Optional[str] = None
|
|
77
|
+
error: Optional[str] = None
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@dataclass
|
|
81
|
+
class ResearchPlan:
|
|
82
|
+
"""Complete research plan with metadata."""
|
|
83
|
+
actions: List[str]
|
|
84
|
+
total_cost: float
|
|
85
|
+
state_progression: List[Set[str]]
|
|
86
|
+
verification_mode: VerificationMode
|
|
87
|
+
estimated_confidence: float
|
|
88
|
+
unsigned_claims_count: int
|
|
89
|
+
|
|
90
|
+
def to_dict(self) -> Dict:
|
|
91
|
+
return {
|
|
92
|
+
'actions': self.actions,
|
|
93
|
+
'total_cost': self.total_cost,
|
|
94
|
+
'state_progression': [list(s) for s in self.state_progression],
|
|
95
|
+
'verification_mode': self.verification_mode.name,
|
|
96
|
+
'estimated_confidence': self.estimated_confidence,
|
|
97
|
+
'unsigned_claims_count': self.unsigned_claims_count
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
# Extended research actions library with Ed25519 verification support
|
|
102
|
+
RESEARCH_ACTIONS = [
|
|
103
|
+
# Setup Actions
|
|
104
|
+
ResearchAction(
|
|
105
|
+
name="configure_trusted_issuers",
|
|
106
|
+
preconditions=set(),
|
|
107
|
+
effects={"whitelist_active", "verification_ready"},
|
|
108
|
+
cost=0,
|
|
109
|
+
description="Initialize trusted issuer whitelist"
|
|
110
|
+
),
|
|
111
|
+
ResearchAction(
|
|
112
|
+
name="generate_research_keypair",
|
|
113
|
+
preconditions=set(),
|
|
114
|
+
effects={"keypair_available", "signing_ready"},
|
|
115
|
+
cost=1,
|
|
116
|
+
description="Generate Ed25519 keypair for signing"
|
|
117
|
+
),
|
|
118
|
+
|
|
119
|
+
# Search Actions
|
|
120
|
+
ResearchAction(
|
|
121
|
+
name="web_search_broad",
|
|
122
|
+
preconditions={"topic_defined"},
|
|
123
|
+
effects={"candidates_found", "subtopics_identified"},
|
|
124
|
+
cost=1,
|
|
125
|
+
description="Initial broad search to identify landscape"
|
|
126
|
+
),
|
|
127
|
+
ResearchAction(
|
|
128
|
+
name="web_search_verified",
|
|
129
|
+
preconditions={"topic_defined", "whitelist_active"},
|
|
130
|
+
effects={"verified_candidates_found", "trusted_sources_identified"},
|
|
131
|
+
cost=2,
|
|
132
|
+
description="Search with priority to trusted issuer sources",
|
|
133
|
+
requires_verification=True,
|
|
134
|
+
verification_type="domain"
|
|
135
|
+
),
|
|
136
|
+
ResearchAction(
|
|
137
|
+
name="web_search_specific",
|
|
138
|
+
preconditions={"subtopics_identified"},
|
|
139
|
+
effects={"detail_found", "sources_identified"},
|
|
140
|
+
cost=1,
|
|
141
|
+
description="Targeted search for specific information"
|
|
142
|
+
),
|
|
143
|
+
ResearchAction(
|
|
144
|
+
name="web_search_expert",
|
|
145
|
+
preconditions={"topic_defined"},
|
|
146
|
+
effects={"authorities_found", "expert_opinions_available"},
|
|
147
|
+
cost=2,
|
|
148
|
+
description="Find domain experts and authoritative sources"
|
|
149
|
+
),
|
|
150
|
+
|
|
151
|
+
# Content Retrieval Actions
|
|
152
|
+
ResearchAction(
|
|
153
|
+
name="fetch_source",
|
|
154
|
+
preconditions={"sources_identified"},
|
|
155
|
+
effects={"content_retrieved", "full_context_available"},
|
|
156
|
+
cost=2,
|
|
157
|
+
description="Retrieve full content from identified sources"
|
|
158
|
+
),
|
|
159
|
+
ResearchAction(
|
|
160
|
+
name="fetch_signed_source",
|
|
161
|
+
preconditions={"sources_identified", "whitelist_active"},
|
|
162
|
+
effects={"signed_content_retrieved", "signature_verified"},
|
|
163
|
+
cost=3,
|
|
164
|
+
description="Retrieve content with Ed25519 signature verification",
|
|
165
|
+
requires_verification=True,
|
|
166
|
+
verification_type="signature"
|
|
167
|
+
),
|
|
168
|
+
|
|
169
|
+
# Extraction Actions
|
|
170
|
+
ResearchAction(
|
|
171
|
+
name="extract_facts",
|
|
172
|
+
preconditions={"content_retrieved"},
|
|
173
|
+
effects={"facts_cataloged", "claims_identified"},
|
|
174
|
+
cost=1,
|
|
175
|
+
description="Extract verifiable claims from content"
|
|
176
|
+
),
|
|
177
|
+
ResearchAction(
|
|
178
|
+
name="sign_extracted_facts",
|
|
179
|
+
preconditions={"facts_cataloged", "keypair_available"},
|
|
180
|
+
effects={"signed_facts", "researcher_signature_attached"},
|
|
181
|
+
cost=2,
|
|
182
|
+
description="Cryptographically sign extracted facts",
|
|
183
|
+
requires_verification=True,
|
|
184
|
+
verification_type="signature"
|
|
185
|
+
),
|
|
186
|
+
|
|
187
|
+
# Verification Actions
|
|
188
|
+
ResearchAction(
|
|
189
|
+
name="verify_claim",
|
|
190
|
+
preconditions={"claims_identified", "sources_identified"},
|
|
191
|
+
effects={"claims_verified"},
|
|
192
|
+
cost=3,
|
|
193
|
+
description="Verify specific claims against sources"
|
|
194
|
+
),
|
|
195
|
+
ResearchAction(
|
|
196
|
+
name="verify_claim_cryptographic",
|
|
197
|
+
preconditions={"claims_identified", "signed_content_retrieved"},
|
|
198
|
+
effects={"cryptographically_verified"},
|
|
199
|
+
cost=4,
|
|
200
|
+
description="Verify claim with Ed25519 cryptographic proof",
|
|
201
|
+
requires_verification=True,
|
|
202
|
+
verification_type="signature"
|
|
203
|
+
),
|
|
204
|
+
ResearchAction(
|
|
205
|
+
name="cross_reference",
|
|
206
|
+
preconditions={"facts_cataloged", "sources_identified"},
|
|
207
|
+
effects={"consistency_checked", "contradictions_identified"},
|
|
208
|
+
cost=2,
|
|
209
|
+
description="Check consistency across multiple sources"
|
|
210
|
+
),
|
|
211
|
+
ResearchAction(
|
|
212
|
+
name="cross_reference_signed",
|
|
213
|
+
preconditions={"signed_facts", "trusted_sources_identified"},
|
|
214
|
+
effects={"signed_consistency_checked", "multi_source_verified"},
|
|
215
|
+
cost=3,
|
|
216
|
+
description="Cross-reference with signed source verification",
|
|
217
|
+
requires_verification=True,
|
|
218
|
+
verification_type="multi-sig"
|
|
219
|
+
),
|
|
220
|
+
ResearchAction(
|
|
221
|
+
name="find_primary_source",
|
|
222
|
+
preconditions={"claims_identified"},
|
|
223
|
+
effects={"primary_located", "original_source_available"},
|
|
224
|
+
cost=3,
|
|
225
|
+
description="Trace claims to original sources"
|
|
226
|
+
),
|
|
227
|
+
|
|
228
|
+
# Citation Chain Actions
|
|
229
|
+
ResearchAction(
|
|
230
|
+
name="build_citation_chain",
|
|
231
|
+
preconditions={"facts_cataloged"},
|
|
232
|
+
effects={"citation_chain_complete"},
|
|
233
|
+
cost=2,
|
|
234
|
+
description="Construct linked chain of cited facts"
|
|
235
|
+
),
|
|
236
|
+
ResearchAction(
|
|
237
|
+
name="verify_citation_chain",
|
|
238
|
+
preconditions={"citation_chain_complete", "signed_facts"},
|
|
239
|
+
effects={"chain_verified"},
|
|
240
|
+
cost=3,
|
|
241
|
+
description="Verify entire citation chain integrity",
|
|
242
|
+
requires_verification=True,
|
|
243
|
+
verification_type="chain"
|
|
244
|
+
),
|
|
245
|
+
|
|
246
|
+
# Analysis Actions
|
|
247
|
+
ResearchAction(
|
|
248
|
+
name="identify_patterns",
|
|
249
|
+
preconditions={"facts_cataloged"},
|
|
250
|
+
effects={"patterns_identified", "themes_emerged"},
|
|
251
|
+
cost=2,
|
|
252
|
+
description="Discover recurring themes and connections"
|
|
253
|
+
),
|
|
254
|
+
ResearchAction(
|
|
255
|
+
name="timeline_construction",
|
|
256
|
+
preconditions={"facts_cataloged"},
|
|
257
|
+
effects={"chronology_established", "sequence_clear"},
|
|
258
|
+
cost=2,
|
|
259
|
+
description="Establish chronological sequence of events"
|
|
260
|
+
),
|
|
261
|
+
ResearchAction(
|
|
262
|
+
name="compare_perspectives",
|
|
263
|
+
preconditions={"content_retrieved", "authorities_found"},
|
|
264
|
+
effects={"viewpoints_mapped", "disagreements_clarified"},
|
|
265
|
+
cost=2,
|
|
266
|
+
description="Document different viewpoints on topic"
|
|
267
|
+
),
|
|
268
|
+
|
|
269
|
+
# Synthesis Actions
|
|
270
|
+
ResearchAction(
|
|
271
|
+
name="synthesize_findings",
|
|
272
|
+
preconditions={"claims_verified", "patterns_identified"},
|
|
273
|
+
effects={"conclusions_formed", "confidence_assigned"},
|
|
274
|
+
cost=3,
|
|
275
|
+
description="Integrate research into coherent conclusions"
|
|
276
|
+
),
|
|
277
|
+
ResearchAction(
|
|
278
|
+
name="synthesize_verified_findings",
|
|
279
|
+
preconditions={"cryptographically_verified", "patterns_identified"},
|
|
280
|
+
effects={"verified_conclusions_formed", "high_confidence_assigned"},
|
|
281
|
+
cost=3,
|
|
282
|
+
description="Synthesize cryptographically verified findings"
|
|
283
|
+
),
|
|
284
|
+
ResearchAction(
|
|
285
|
+
name="generate_report",
|
|
286
|
+
preconditions={"conclusions_formed"},
|
|
287
|
+
effects={"report_delivered", "research_complete"},
|
|
288
|
+
cost=2,
|
|
289
|
+
description="Produce structured research output"
|
|
290
|
+
),
|
|
291
|
+
ResearchAction(
|
|
292
|
+
name="generate_signed_report",
|
|
293
|
+
preconditions={"conclusions_formed", "keypair_available"},
|
|
294
|
+
effects={"signed_report_delivered", "verification_ledger_attached"},
|
|
295
|
+
cost=3,
|
|
296
|
+
description="Produce cryptographically signed research report",
|
|
297
|
+
requires_verification=True,
|
|
298
|
+
verification_type="signature"
|
|
299
|
+
),
|
|
300
|
+
|
|
301
|
+
# Recovery Actions
|
|
302
|
+
ResearchAction(
|
|
303
|
+
name="expand_search",
|
|
304
|
+
preconditions={"dead_end_reached"},
|
|
305
|
+
effects={"new_candidates_found"},
|
|
306
|
+
cost=1,
|
|
307
|
+
description="Broaden search when stuck"
|
|
308
|
+
),
|
|
309
|
+
ResearchAction(
|
|
310
|
+
name="recover_from_verification_failure",
|
|
311
|
+
preconditions={"signature_invalid"},
|
|
312
|
+
effects={"alternative_source_found"},
|
|
313
|
+
cost=2,
|
|
314
|
+
description="Handle failed signature verification"
|
|
315
|
+
),
|
|
316
|
+
]
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def heuristic(state: Set[str], goal: Set[str], unsigned_claims: int = 0) -> float:
|
|
320
|
+
"""
|
|
321
|
+
Estimate cost to reach goal from current state.
|
|
322
|
+
|
|
323
|
+
Includes verification penalty for unsigned claims.
|
|
324
|
+
"""
|
|
325
|
+
missing = goal - state
|
|
326
|
+
base_cost = len(missing) * 1.5 # Weighted by average action cost
|
|
327
|
+
verification_penalty = unsigned_claims * 0.5 # Penalty for unsigned content
|
|
328
|
+
return base_cost + verification_penalty
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
def find_research_plan(
|
|
332
|
+
initial_state: Set[str],
|
|
333
|
+
goal_state: Set[str],
|
|
334
|
+
actions: List[ResearchAction] = None,
|
|
335
|
+
verification_mode: VerificationMode = VerificationMode.MODERATE,
|
|
336
|
+
max_iterations: int = 1000
|
|
337
|
+
) -> Optional[ResearchPlan]:
|
|
338
|
+
"""
|
|
339
|
+
A* search to find optimal research plan with verification support.
|
|
340
|
+
|
|
341
|
+
Args:
|
|
342
|
+
initial_state: Starting conditions
|
|
343
|
+
goal_state: Target conditions to achieve
|
|
344
|
+
actions: Available actions (defaults to RESEARCH_ACTIONS)
|
|
345
|
+
verification_mode: How strict to be about verification
|
|
346
|
+
max_iterations: Maximum search iterations
|
|
347
|
+
|
|
348
|
+
Returns:
|
|
349
|
+
ResearchPlan object or None if no plan found
|
|
350
|
+
"""
|
|
351
|
+
if actions is None:
|
|
352
|
+
actions = RESEARCH_ACTIONS
|
|
353
|
+
|
|
354
|
+
# Check if goal already satisfied
|
|
355
|
+
if goal_state.issubset(initial_state):
|
|
356
|
+
return ResearchPlan(
|
|
357
|
+
actions=[],
|
|
358
|
+
total_cost=0.0,
|
|
359
|
+
state_progression=[initial_state],
|
|
360
|
+
verification_mode=verification_mode,
|
|
361
|
+
estimated_confidence=1.0,
|
|
362
|
+
unsigned_claims_count=0
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
# Priority queue
|
|
366
|
+
start_h = heuristic(initial_state, goal_state)
|
|
367
|
+
open_set = [PlanNode(start_h, 0, frozenset(initial_state), [], 0)]
|
|
368
|
+
|
|
369
|
+
# Track visited states
|
|
370
|
+
visited: Set[frozenset] = set()
|
|
371
|
+
|
|
372
|
+
# Verification settings
|
|
373
|
+
require_verification = verification_mode in [VerificationMode.STRICT, VerificationMode.PARANOID]
|
|
374
|
+
|
|
375
|
+
iterations = 0
|
|
376
|
+
while open_set and iterations < max_iterations:
|
|
377
|
+
iterations += 1
|
|
378
|
+
|
|
379
|
+
current = heapq.heappop(open_set)
|
|
380
|
+
current_state = set(current.state)
|
|
381
|
+
|
|
382
|
+
# Goal check
|
|
383
|
+
if goal_state.issubset(current_state):
|
|
384
|
+
# Check if verification requirements are met
|
|
385
|
+
if require_verification and current.unsigned_claims > 0:
|
|
386
|
+
# In strict/paranoid mode, penalize but don't reject
|
|
387
|
+
pass
|
|
388
|
+
|
|
389
|
+
# Reconstruct state progression
|
|
390
|
+
states = [initial_state]
|
|
391
|
+
state = initial_state.copy()
|
|
392
|
+
for action_name in current.actions:
|
|
393
|
+
action = next(a for a in actions if a.name == action_name)
|
|
394
|
+
state = action.apply(state)
|
|
395
|
+
states.append(state.copy())
|
|
396
|
+
|
|
397
|
+
# Calculate confidence based on verification
|
|
398
|
+
base_confidence = 1.0 - (current.unsigned_claims * 0.1)
|
|
399
|
+
estimated_confidence = max(0.5, min(1.0, base_confidence))
|
|
400
|
+
|
|
401
|
+
return ResearchPlan(
|
|
402
|
+
actions=current.actions,
|
|
403
|
+
total_cost=current.g_cost,
|
|
404
|
+
state_progression=states,
|
|
405
|
+
verification_mode=verification_mode,
|
|
406
|
+
estimated_confidence=estimated_confidence,
|
|
407
|
+
unsigned_claims_count=current.unsigned_claims
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
# Skip if already visited
|
|
411
|
+
if current.state in visited:
|
|
412
|
+
continue
|
|
413
|
+
visited.add(current.state)
|
|
414
|
+
|
|
415
|
+
# Expand neighbors
|
|
416
|
+
for action in actions:
|
|
417
|
+
if action.is_applicable(current_state):
|
|
418
|
+
new_state = action.apply(current_state)
|
|
419
|
+
new_state_frozen = frozenset(new_state)
|
|
420
|
+
|
|
421
|
+
if new_state_frozen not in visited:
|
|
422
|
+
# Calculate cost with verification overhead
|
|
423
|
+
action_cost = action.get_total_cost(require_verification)
|
|
424
|
+
new_g = current.g_cost + action_cost
|
|
425
|
+
|
|
426
|
+
# Track unsigned claims
|
|
427
|
+
new_unsigned = current.unsigned_claims
|
|
428
|
+
if 'claims_identified' in new_state and 'signed_facts' not in new_state:
|
|
429
|
+
new_unsigned += 1
|
|
430
|
+
if 'signed_facts' in new_state or 'cryptographically_verified' in new_state:
|
|
431
|
+
new_unsigned = max(0, new_unsigned - 1)
|
|
432
|
+
|
|
433
|
+
new_h = heuristic(new_state, goal_state, new_unsigned)
|
|
434
|
+
new_f = new_g + new_h
|
|
435
|
+
|
|
436
|
+
new_node = PlanNode(
|
|
437
|
+
f_cost=new_f,
|
|
438
|
+
g_cost=new_g,
|
|
439
|
+
state=new_state_frozen,
|
|
440
|
+
actions=current.actions + [action.name],
|
|
441
|
+
unsigned_claims=new_unsigned
|
|
442
|
+
)
|
|
443
|
+
heapq.heappush(open_set, new_node)
|
|
444
|
+
|
|
445
|
+
return None # No plan found
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
def format_plan(plan: ResearchPlan, action_library: List[ResearchAction] = None) -> str:
|
|
449
|
+
"""Format research plan for display."""
|
|
450
|
+
if action_library is None:
|
|
451
|
+
action_library = RESEARCH_ACTIONS
|
|
452
|
+
|
|
453
|
+
action_map = {a.name: a for a in action_library}
|
|
454
|
+
|
|
455
|
+
# Verification status indicator
|
|
456
|
+
if plan.verification_mode == VerificationMode.PARANOID:
|
|
457
|
+
mode_indicator = "🔒 PARANOID (0.99)"
|
|
458
|
+
elif plan.verification_mode == VerificationMode.STRICT:
|
|
459
|
+
mode_indicator = "🛡️ STRICT (0.95)"
|
|
460
|
+
elif plan.verification_mode == VerificationMode.MODERATE:
|
|
461
|
+
mode_indicator = "✓ MODERATE (0.85)"
|
|
462
|
+
else:
|
|
463
|
+
mode_indicator = "⚡ DEVELOPMENT (0.75)"
|
|
464
|
+
|
|
465
|
+
lines = [
|
|
466
|
+
"=" * 70,
|
|
467
|
+
"GOAP RESEARCH PLAN (Ed25519 Enhanced)",
|
|
468
|
+
"=" * 70,
|
|
469
|
+
f"Verification Mode: {mode_indicator}",
|
|
470
|
+
f"Total Cost: {plan.total_cost}",
|
|
471
|
+
f"Steps: {len(plan.actions)}",
|
|
472
|
+
f"Estimated Confidence: {plan.estimated_confidence:.2%}",
|
|
473
|
+
f"Unsigned Claims: {plan.unsigned_claims_count}",
|
|
474
|
+
"",
|
|
475
|
+
"EXECUTION SEQUENCE:",
|
|
476
|
+
"-" * 50,
|
|
477
|
+
]
|
|
478
|
+
|
|
479
|
+
for i, action_name in enumerate(plan.actions, 1):
|
|
480
|
+
action = action_map.get(action_name)
|
|
481
|
+
if action:
|
|
482
|
+
# Verification indicator
|
|
483
|
+
if action.requires_verification:
|
|
484
|
+
ver_icon = "🔐"
|
|
485
|
+
else:
|
|
486
|
+
ver_icon = " "
|
|
487
|
+
|
|
488
|
+
lines.append(f"\n{ver_icon} Step {i}: {action.name}")
|
|
489
|
+
lines.append(f" Description: {action.description}")
|
|
490
|
+
lines.append(f" Cost: {action.cost}" +
|
|
491
|
+
(" (+1 verification)" if action.requires_verification else ""))
|
|
492
|
+
lines.append(f" Requires: {', '.join(action.preconditions) or 'None'}")
|
|
493
|
+
lines.append(f" Produces: {', '.join(action.effects)}")
|
|
494
|
+
|
|
495
|
+
if action.verification_type:
|
|
496
|
+
lines.append(f" Verification: {action.verification_type}")
|
|
497
|
+
|
|
498
|
+
if i < len(plan.state_progression):
|
|
499
|
+
new_effects = plan.state_progression[i] - plan.state_progression[i-1]
|
|
500
|
+
if new_effects:
|
|
501
|
+
lines.append(f" New state: +{', '.join(sorted(new_effects))}")
|
|
502
|
+
|
|
503
|
+
lines.extend([
|
|
504
|
+
"",
|
|
505
|
+
"=" * 70,
|
|
506
|
+
"FINAL STATE ACHIEVED:",
|
|
507
|
+
"-" * 50,
|
|
508
|
+
", ".join(sorted(plan.state_progression[-1])) if plan.state_progression else "N/A",
|
|
509
|
+
"",
|
|
510
|
+
"VERIFICATION SUMMARY:",
|
|
511
|
+
"-" * 50,
|
|
512
|
+
f"Mode: {plan.verification_mode.name}",
|
|
513
|
+
f"Threshold: {plan.verification_mode.value}",
|
|
514
|
+
f"Estimated Confidence: {plan.estimated_confidence:.2%}",
|
|
515
|
+
f"Meets Threshold: {'✅ YES' if plan.estimated_confidence >= plan.verification_mode.value else '❌ NO'}",
|
|
516
|
+
"=" * 70,
|
|
517
|
+
])
|
|
518
|
+
|
|
519
|
+
return "\n".join(lines)
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
def create_research_goal(
|
|
523
|
+
goal_type: str,
|
|
524
|
+
verification_mode: VerificationMode = VerificationMode.MODERATE
|
|
525
|
+
) -> Tuple[Set[str], Set[str]]:
|
|
526
|
+
"""
|
|
527
|
+
Create initial and goal states for common research types.
|
|
528
|
+
|
|
529
|
+
Args:
|
|
530
|
+
goal_type: One of 'exploratory', 'verified_exploratory', 'verification',
|
|
531
|
+
'competitive', 'technology', 'quick', 'high_stakes'
|
|
532
|
+
verification_mode: Affects which goals require verification
|
|
533
|
+
|
|
534
|
+
Returns:
|
|
535
|
+
Tuple of (initial_state, goal_state)
|
|
536
|
+
"""
|
|
537
|
+
initial = {"topic_defined"}
|
|
538
|
+
|
|
539
|
+
goals = {
|
|
540
|
+
"exploratory": {
|
|
541
|
+
"research_complete",
|
|
542
|
+
"conclusions_formed",
|
|
543
|
+
"patterns_identified",
|
|
544
|
+
"claims_verified"
|
|
545
|
+
},
|
|
546
|
+
"verified_exploratory": {
|
|
547
|
+
"signed_report_delivered",
|
|
548
|
+
"verified_conclusions_formed",
|
|
549
|
+
"chain_verified",
|
|
550
|
+
"high_confidence_assigned"
|
|
551
|
+
},
|
|
552
|
+
"verification": {
|
|
553
|
+
"claims_verified",
|
|
554
|
+
"primary_located",
|
|
555
|
+
"consistency_checked"
|
|
556
|
+
},
|
|
557
|
+
"cryptographic_verification": {
|
|
558
|
+
"cryptographically_verified",
|
|
559
|
+
"chain_verified",
|
|
560
|
+
"signed_report_delivered"
|
|
561
|
+
},
|
|
562
|
+
"competitive": {
|
|
563
|
+
"viewpoints_mapped",
|
|
564
|
+
"conclusions_formed",
|
|
565
|
+
"patterns_identified"
|
|
566
|
+
},
|
|
567
|
+
"verified_competitive": {
|
|
568
|
+
"viewpoints_mapped",
|
|
569
|
+
"verified_conclusions_formed",
|
|
570
|
+
"signed_report_delivered"
|
|
571
|
+
},
|
|
572
|
+
"technology": {
|
|
573
|
+
"conclusions_formed",
|
|
574
|
+
"claims_verified",
|
|
575
|
+
"expert_opinions_available"
|
|
576
|
+
},
|
|
577
|
+
"quick": {
|
|
578
|
+
"facts_cataloged",
|
|
579
|
+
"content_retrieved"
|
|
580
|
+
},
|
|
581
|
+
"high_stakes": {
|
|
582
|
+
"signed_report_delivered",
|
|
583
|
+
"chain_verified",
|
|
584
|
+
"cryptographically_verified",
|
|
585
|
+
"multi_source_verified",
|
|
586
|
+
"verification_ledger_attached"
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
# Auto-upgrade to verified version in strict/paranoid mode
|
|
591
|
+
if verification_mode in [VerificationMode.STRICT, VerificationMode.PARANOID]:
|
|
592
|
+
upgrades = {
|
|
593
|
+
"exploratory": "verified_exploratory",
|
|
594
|
+
"verification": "cryptographic_verification",
|
|
595
|
+
"competitive": "verified_competitive"
|
|
596
|
+
}
|
|
597
|
+
goal_type = upgrades.get(goal_type, goal_type)
|
|
598
|
+
|
|
599
|
+
return initial, goals.get(goal_type, goals["exploratory"])
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
class GOAPResearchPlanner:
|
|
603
|
+
"""
|
|
604
|
+
High-level interface for GOAP research planning with Ed25519 verification.
|
|
605
|
+
"""
|
|
606
|
+
|
|
607
|
+
def __init__(
|
|
608
|
+
self,
|
|
609
|
+
verification_mode: str = "moderate",
|
|
610
|
+
trusted_issuers: Optional[List[str]] = None
|
|
611
|
+
):
|
|
612
|
+
"""
|
|
613
|
+
Initialize planner.
|
|
614
|
+
|
|
615
|
+
Args:
|
|
616
|
+
verification_mode: 'development', 'moderate', 'strict', or 'paranoid'
|
|
617
|
+
trusted_issuers: List of trusted issuer domains
|
|
618
|
+
"""
|
|
619
|
+
mode_map = {
|
|
620
|
+
"development": VerificationMode.DEVELOPMENT,
|
|
621
|
+
"moderate": VerificationMode.MODERATE,
|
|
622
|
+
"strict": VerificationMode.STRICT,
|
|
623
|
+
"paranoid": VerificationMode.PARANOID
|
|
624
|
+
}
|
|
625
|
+
self.verification_mode = mode_map.get(verification_mode.lower(), VerificationMode.MODERATE)
|
|
626
|
+
self.trusted_issuers = trusted_issuers or []
|
|
627
|
+
self.verification_ledger: List[VerificationResult] = []
|
|
628
|
+
|
|
629
|
+
def plan(
|
|
630
|
+
self,
|
|
631
|
+
goal_type: str,
|
|
632
|
+
topic: str,
|
|
633
|
+
custom_goals: Optional[Set[str]] = None
|
|
634
|
+
) -> Optional[ResearchPlan]:
|
|
635
|
+
"""
|
|
636
|
+
Generate research plan for given goal type.
|
|
637
|
+
|
|
638
|
+
Args:
|
|
639
|
+
goal_type: Type of research (see create_research_goal)
|
|
640
|
+
topic: Research topic (for logging)
|
|
641
|
+
custom_goals: Override default goals
|
|
642
|
+
|
|
643
|
+
Returns:
|
|
644
|
+
ResearchPlan or None
|
|
645
|
+
"""
|
|
646
|
+
initial, goal = create_research_goal(goal_type, self.verification_mode)
|
|
647
|
+
|
|
648
|
+
if custom_goals:
|
|
649
|
+
goal = custom_goals
|
|
650
|
+
|
|
651
|
+
# Add verification-related initial state if configured
|
|
652
|
+
if self.trusted_issuers:
|
|
653
|
+
initial.add("whitelist_available")
|
|
654
|
+
|
|
655
|
+
return find_research_plan(
|
|
656
|
+
initial_state=initial,
|
|
657
|
+
goal_state=goal,
|
|
658
|
+
verification_mode=self.verification_mode
|
|
659
|
+
)
|
|
660
|
+
|
|
661
|
+
def format_plan(self, plan: ResearchPlan) -> str:
|
|
662
|
+
"""Format plan for display."""
|
|
663
|
+
return format_plan(plan)
|
|
664
|
+
|
|
665
|
+
def export_plan(self, plan: ResearchPlan) -> str:
|
|
666
|
+
"""Export plan as JSON."""
|
|
667
|
+
return json.dumps(plan.to_dict(), indent=2)
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
# Example usage and demonstration
|
|
671
|
+
if __name__ == "__main__":
|
|
672
|
+
print("GOAP Research Planner with Ed25519 Verification")
|
|
673
|
+
print("=" * 70)
|
|
674
|
+
|
|
675
|
+
# Example 1: Standard exploratory research
|
|
676
|
+
print("\n[1] STANDARD EXPLORATORY RESEARCH (Moderate Mode)")
|
|
677
|
+
print("-" * 50)
|
|
678
|
+
|
|
679
|
+
initial, goal = create_research_goal("exploratory", VerificationMode.MODERATE)
|
|
680
|
+
print(f"Initial State: {initial}")
|
|
681
|
+
print(f"Goal State: {goal}")
|
|
682
|
+
|
|
683
|
+
plan = find_research_plan(initial, goal, verification_mode=VerificationMode.MODERATE)
|
|
684
|
+
if plan:
|
|
685
|
+
print(format_plan(plan))
|
|
686
|
+
else:
|
|
687
|
+
print("No plan found!")
|
|
688
|
+
|
|
689
|
+
# Example 2: High-stakes verified research
|
|
690
|
+
print("\n\n[2] HIGH-STAKES VERIFIED RESEARCH (Strict Mode)")
|
|
691
|
+
print("-" * 50)
|
|
692
|
+
|
|
693
|
+
initial, goal = create_research_goal("high_stakes", VerificationMode.STRICT)
|
|
694
|
+
print(f"Initial State: {initial}")
|
|
695
|
+
print(f"Goal State: {goal}")
|
|
696
|
+
|
|
697
|
+
plan = find_research_plan(initial, goal, verification_mode=VerificationMode.STRICT)
|
|
698
|
+
if plan:
|
|
699
|
+
print(format_plan(plan))
|
|
700
|
+
else:
|
|
701
|
+
print("No plan found!")
|
|
702
|
+
|
|
703
|
+
# Example 3: Using the high-level planner interface
|
|
704
|
+
print("\n\n[3] HIGH-LEVEL PLANNER INTERFACE")
|
|
705
|
+
print("-" * 50)
|
|
706
|
+
|
|
707
|
+
planner = GOAPResearchPlanner(
|
|
708
|
+
verification_mode="strict",
|
|
709
|
+
trusted_issuers=["reuters.com", "nature.com", "arxiv.org"]
|
|
710
|
+
)
|
|
711
|
+
|
|
712
|
+
plan = planner.plan(
|
|
713
|
+
goal_type="verified_exploratory",
|
|
714
|
+
topic="AI safety regulations 2025"
|
|
715
|
+
)
|
|
716
|
+
|
|
717
|
+
if plan:
|
|
718
|
+
print(planner.format_plan(plan))
|
|
719
|
+
print("\nJSON Export:")
|
|
720
|
+
print(planner.export_plan(plan))
|