# Plan Execute: Strategize & Execute Integration ## Overview The plan executor connects the `PlanLifecycleService` to stub actors that drive plans through the **Strategize** and **Execute** phases. In M1, these actors are local-only stubs (no LLM calls); future milestones will integrate real AI providers. ## Architecture ``` PlanExecutor ├── StrategizeStubActor (read-only, produces decision tree) ├── ExecuteStubActor (sandbox + ToolRunner + ChangeSet capture) └── PlanLifecycleService (phase transitions, persistence) ``` ## Phase Lifecycle | Phase | Actor | Mode | Output | |-------------|---------------------|-----------|---------------------------------| | Strategize | StrategizeStubActor | Read-only | Decision tree, invariant records| | Execute | ExecuteStubActor | Sandbox | ChangeSet, execution metadata | ## Strategize Phase The strategize phase is **read-only**: it produces a decision tree from the action's `definition_of_done` without modifying any resources. ### Decision Tree The stub actor parses `definition_of_done` into discrete steps, each represented as a `StrategyDecision` node with a ULID identifier: ```python from cleveragents.application.services.plan_executor import ( PlanExecutor, StrategizeResult, ) executor = PlanExecutor(lifecycle_service=lifecycle, tool_runner=runner) result: StrategizeResult = executor.run_strategize(plan_id) # result.decision_root_id -> ULID of root node # result.decisions -> list[StrategyDecision] # result.invariant_records -> list[dict] (stub enforcement records) ``` ### Invariant Propagation Project and action invariants are propagated into the strategize context. In M1, enforcement is stubbed (all invariants are accepted). Full reconciliation via the Invariant Reconciliation Actor lands in D2. ## Execute Phase The execute phase uses sandbox resources with tool calls routed through `ToolRunner` and captured by `ChangeSetCapture`. ### ChangeSet Capture All tool mutations during execute are recorded in a `ChangeSet`: ```python result: ExecuteResult = executor.run_execute(plan_id) # result.changeset_id -> ULID of the changeset # result.changeset -> ChangeSet with entries # result.tool_calls_count -> int # result.sandbox_refs -> list[str] ``` ### Metadata Persistence After execute completes, the following metadata is persisted on the Plan: - `changeset_id`: The ChangeSet identifier - `sandbox_refs`: List of sandbox reference paths - `error_details`: Tool call count and sandbox ref count ## Phase Guards - **Execute requires Strategize COMPLETE**: The executor validates that the plan has completed strategize (has a `decision_root_id`) before allowing execute to proceed. - **Phase validation**: Both `run_strategize()` and `run_execute()` verify the plan is in the correct phase before proceeding. ## Error Handling Failures in either phase are captured with full error context: - `error_message`: The exception message string - `error_details`: Dict containing `exception_type` and `traceback` - The plan transitions to `ERRORED` processing state ### Retry Guidance Plans in `ERRORED` state can be retried by: 1. Resetting the plan's processing state back to `QUEUED` 2. Re-running the failed phase via the executor Full retry automation is planned for D1b (Phase Reversion & Error Recovery). ## Streaming Hooks Both phases accept an optional `stream_callback` parameter for real-time status updates (used by the `--stream` CLI flag): ```python def my_callback(event_type: str, data: dict) -> None: print(f"[{event_type}] {data}") executor.run_strategize(plan_id, stream_callback=my_callback) ``` ### Event Types | Event | Phase | Description | |------------------------|------------|---------------------------------| | `strategize_started` | Strategize | Phase processing began | | `strategize_decisions` | Strategize | Decisions produced | | `strategize_complete` | Strategize | Phase completed successfully | | `execute_started` | Execute | Phase processing began | | `execute_step` | Execute | Individual decision being executed | | `execute_complete` | Execute | Phase completed successfully | ## Module Reference - **`cleveragents.application.services.plan_executor`**: Core module - `StrategizeStubActor`: Local-only strategize actor - `ExecuteStubActor`: Local-only execute actor - `PlanExecutor`: Orchestrator connecting lifecycle service to actors - `StrategyDecision`: Decision node model - `StrategizeResult`: Strategize output model - `ExecuteResult`: Execute output model - `StreamCallback`: Type alias for streaming callbacks