feat(strategist) S3: propose_lead / declare_investigation_complete
DESIGN_STRATEGIST.md §2.5. The strategist's two write actions. propose_lead validates motivating_hypothesis exists in the graph, validates expected_evidence_type is a real edge type, validates source_id refers to a real source in the case — fast specific errors so the strategist gets fixable feedback rather than a generic crash. On success, calls graph.add_lead with proposed_by= "strategist" and round_number=graph.current_strategist_round so the round-completion code can collect this round's leads. declare_investigation_complete sets graph.strategist_complete_requested which the orchestrator inspects after each strategist run to decide whether to break the loop. reason must come from a closed enum so the audit log is consistent. EvidenceGraph gains two transient run-context fields: current_strategist_round — set by orchestrator at start of round strategist_complete_requested — flipped by declare_complete These are intentionally NOT persisted — they're per-run flags, not graph state. Both tools required to be in InvestigationStrategist.mandatory_record_ tools (added in S4) so the agent's forced-retry mechanism kicks in if it returns without taking a documented decision. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -680,6 +680,15 @@ class EvidenceGraph:
|
||||
self.budgets: dict[str, int] = {}
|
||||
self.run_start_monotonic: float | None = None
|
||||
|
||||
# Current strategist round number. Set by the orchestrator at the
|
||||
# top of each strategist loop iteration so propose_lead / declare_
|
||||
# investigation_complete can tag their actions correctly. 0 when
|
||||
# the strategist is not running.
|
||||
self.current_strategist_round: int = 0
|
||||
# Set to True by declare_investigation_complete so the orchestrator
|
||||
# knows to break out of the strategist loop after this round.
|
||||
self.strategist_complete_requested: bool = False
|
||||
|
||||
# _current_agent / _current_task_id are exposed as @property below,
|
||||
# backed by module-level ContextVars (race-free under asyncio.gather).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user