Feature: PlanExecutor coverage for uncovered lines As a developer I want to test uncovered paths in plan_executor.py So that lines 144, 233-235, 273, 483, 490 are covered # --- StrategizeStubActor._parse_steps empty input (line 144) --- Scenario: Parse steps returns default when input is empty string Given a StrategizeStubActor instance for coverage When I call _parse_steps with an empty string Then the parsed steps should be the default fallback Scenario: Parse steps returns default when input is whitespace only Given a StrategizeStubActor instance for coverage When I call _parse_steps with whitespace only Then the parsed steps should be the default fallback # --- StrategizeStubActor.execute happy path --- Scenario: Strategize stub actor produces decisions from definition of done Given a StrategizeStubActor instance for coverage When I execute the strategize stub with a valid plan and definition of done Then the strategize result should contain decisions matching the steps Scenario: Strategize stub actor handles None definition of done Given a StrategizeStubActor instance for coverage When I execute the strategize stub with a None definition of done Then the strategize result should contain the default decision Scenario: Strategize stub actor rejects empty plan_id Given a StrategizeStubActor instance for coverage When I execute the strategize stub with an empty plan_id Then a plan executor ValidationError should be raised containing "plan_id" Scenario: Strategize stub actor processes invariants Given a StrategizeStubActor instance for coverage When I execute the strategize stub with invariants Then the strategize result should contain invariant records Scenario: Strategize stub actor invokes stream callback Given a StrategizeStubActor instance for coverage When I execute the strategize stub with a stream callback Then the stream callback should have been called with strategize events # --- ExecuteStubActor happy path --- Scenario: Execute stub actor produces a changeset Given an ExecuteStubActor instance for coverage When I execute the execute stub with decisions Then the execute result should contain a changeset id Scenario: Execute stub actor rejects empty plan_id Given an ExecuteStubActor instance for coverage When I execute the execute stub with an empty plan_id Then a plan executor ValidationError should be raised containing "plan_id" # --- PlanExecutor construction --- Scenario: PlanExecutor rejects None lifecycle service When I construct a PlanExecutor with None lifecycle service Then a plan executor ValidationError should be raised containing "lifecycle_service" Scenario: PlanExecutor has_runtime is False without execution context Given a fresh mock lifecycle for plan executor coverage When I construct a PlanExecutor without execution context Then plan executor has_runtime should be False Scenario: PlanExecutor changeset_store is None without execution context Given a fresh mock lifecycle for plan executor coverage When I construct a PlanExecutor without execution context Then plan executor changeset_store should be None # --- PlanExecutor.run_strategize happy path --- Scenario: PlanExecutor run_strategize succeeds for a plan in Strategize phase Given a mock lifecycle with a plan in Strategize phase for executor coverage And a PlanExecutor using that lifecycle for coverage When I call run_strategize on the PlanExecutor for coverage Then the strategize result should be returned successfully And the lifecycle should have called start_strategize for coverage And the lifecycle should have called complete_strategize for coverage # --- PlanExecutor.run_strategize exception path (line 273) --- Scenario: PlanExecutor run_strategize handles exception and calls fail_strategize Given a mock lifecycle with a plan in Strategize phase that will fail during execute And a PlanExecutor using that failing lifecycle for coverage When I call run_strategize expecting an exception for coverage Then the lifecycle should have called fail_strategize for coverage # --- PlanExecutor.run_strategize wrong phase --- Scenario: PlanExecutor run_strategize rejects plan not in Strategize phase Given a mock lifecycle with a plan in Execute phase for executor coverage And a PlanExecutor using that lifecycle for coverage When I call run_strategize expecting a PlanError for coverage Then a PlanError should be raised about wrong phase for coverage # --- PlanExecutor._guard_execute: decision_root_id is None (lines 233-235) --- Scenario: Guard execute rejects plan with no decision root id Given a mock lifecycle with an execute-phase plan missing decision_root_id And a PlanExecutor using that lifecycle for coverage When I call guard_execute for the plan for coverage Then a PlanError should be raised about missing decision tree Scenario: Guard execute rejects plan not in Execute phase Given a mock lifecycle with a plan in Strategize phase for guard coverage And a PlanExecutor using that lifecycle for coverage When I call guard_execute expecting wrong phase for coverage Then a PlanError should be raised about not in Execute phase Scenario: Guard execute rejects plan not in queued state Given a mock lifecycle with an execute-phase plan in processing state for coverage And a PlanExecutor using that lifecycle for coverage When I call guard_execute expecting wrong state for coverage Then a PlanError should be raised about not queued # --- PlanExecutor._run_execute_with_stub happy path --- Scenario: Run execute with stub succeeds for a properly configured plan Given a mock lifecycle with a fully configured execute-phase plan for coverage And a PlanExecutor using that lifecycle without runtime for coverage When I call run_execute on the PlanExecutor for coverage Then the execute result should be returned successfully And the lifecycle should have called start_execute for coverage And the lifecycle should have called complete_execute for coverage # --- PlanExecutor._run_execute_with_stub exception path (lines 483, 490) --- Scenario: Run execute with stub handles exception and calls fail_execute Given a mock lifecycle with an execute-phase plan that will fail during stub execute And a PlanExecutor using that failing stub lifecycle for coverage When I call run_execute expecting an exception from stub for coverage Then the lifecycle should have called fail_execute for coverage # --- PlanExecutor.run_execute validation --- Scenario: PlanExecutor run_execute rejects empty plan_id Given a fresh mock lifecycle for plan executor coverage And a PlanExecutor using that lifecycle for coverage When I call run_execute with an empty plan_id for coverage Then a plan executor ValidationError should be raised containing "plan_id" # --- PlanExecutor._build_decisions --- Scenario: Build decisions creates decisions from plan definition of done Given a mock lifecycle with a fully configured execute-phase plan for coverage And a PlanExecutor using that lifecycle without runtime for coverage When I call build_decisions for the plan for coverage Then the decisions should match the plan definition of done steps # --- PlanExecutor.execution_context property --- Scenario: PlanExecutor execution_context returns None without context Given a fresh mock lifecycle for plan executor coverage When I construct a PlanExecutor without execution context Then plan executor execution_context should be None