Feature: Plan Lifecycle Service coverage boost round 2 As a developer I want to exercise remaining uncovered code paths in PlanLifecycleService So that code coverage improves beyond 88.3% Background: Given I have a fresh plan lifecycle service for coverage boost r2 # --------------------------------------------------------------- # Lines 263-276: _consult_error_patterns — guidance injection path # When error_pattern_service is configured and returns guidance, # the formatted guidance is stored in plan.error_details. # --------------------------------------------------------------- Scenario: execute_plan injects preventive guidance from error pattern service Given a plan lifecycle service with a configured error pattern service for r2 And an action "local/pattern-check" exists for coverage boost r2 And a plan advanced to strategize complete for coverage boost r2 When I execute the plan so error patterns are consulted Then the plan error_details should contain preventive_guidance # --------------------------------------------------------------- # Lines 277-282: _consult_error_patterns — exception handler path # When error_pattern_service.match_patterns raises, the exception # is caught and logged without propagating. # --------------------------------------------------------------- Scenario: execute_plan swallows error pattern service exceptions Given a plan lifecycle service with a failing error pattern service for r2 And an action "local/pattern-fail" exists for coverage boost r2 And a plan advanced to strategize complete for coverage boost r2 When I execute the plan and error pattern consultation fails Then the plan should still transition to execute phase without error # --------------------------------------------------------------- # Line 339: save_plan — public persistence convenience method # --------------------------------------------------------------- Scenario: save_plan persists plan updates in memory mode Given an action "local/save-test" exists for coverage boost r2 And a plan created from "local/save-test" for coverage boost r2 When I call save_plan on the plan Then save_plan completes without error # --------------------------------------------------------------- # Lines 416-422: _resolve_actor_registry_entry exception handler # When the actor repository lookup raises, the exception is caught # and None is returned. # --------------------------------------------------------------- Scenario: Actor registry resolution returns None when repository raises Given a plan lifecycle service with a mock unit of work that fails actor lookup When I resolve an actor registry entry for "local/broken-actor" Then the resolved actor entry should be None # --------------------------------------------------------------- # Lines 778-784: use_action — event_bus.emit exception handler # When event_bus.emit raises during use_action, the exception # is caught and the plan is still returned. # --------------------------------------------------------------- Scenario: use_action catches event bus emission failure Given a plan lifecycle service with a failing event bus for r2 And an action "local/event-fail-use" exists for coverage boost r2 When I use action "local/event-fail-use" and event bus emit fails Then the plan should still be created in strategize phase # --------------------------------------------------------------- # Lines 847-850: list_plans — DatabaseError fallback to in-memory # When the persistence layer raises DatabaseError on list_all(), # the service falls back to in-memory cache. # --------------------------------------------------------------- Scenario: list_plans falls back to in-memory cache on DatabaseError Given a plan lifecycle service with a mock unit of work that fails list_all And an in-memory plan exists for the fallback test When I call list_plans on the service with the broken persistence Then the result should contain the in-memory plan # --------------------------------------------------------------- # Lines 909-913: start_strategize — action loading from persistence # When the plan's action_name is not in the _actions cache but is # available via persistence, the service loads it. # --------------------------------------------------------------- Scenario: start_strategize loads action from persistence when not in cache Given a plan lifecycle service with a persisted action for cache miss test And a plan whose action is removed from the in-memory cache When I start strategize on the plan with the cleared cache Then start_strategize should complete successfully # --------------------------------------------------------------- # Lines 1070-1080: execute_plan — event_bus.emit exception handler # When event_bus.emit raises during execute_plan phase transition, # the exception is caught and the plan is still returned. # --------------------------------------------------------------- Scenario: execute_plan catches event bus emission failure on phase change Given a plan lifecycle service with a failing event bus for r2 And an action "local/event-fail-exec" exists for coverage boost r2 And a plan advanced to strategize complete for coverage boost r2 When I execute the plan and event bus emit fails during phase change Then the plan should still transition to execute phase # --------------------------------------------------------------- # Lines 1256-1276: complete_apply — event_bus emit success path # Exercises the event_bus.emit call during complete_apply when # the bus does NOT raise (emitting PLAN_APPLIED event). # --------------------------------------------------------------- Scenario: complete_apply emits PLAN_APPLIED event via event bus Given a plan lifecycle service with a recording event bus for r2 And an action "local/apply-event" exists for coverage boost r2 And a plan advanced to apply processing for coverage boost r2 When I complete apply on the plan with event bus Then the event bus should have recorded a PLAN_APPLIED event # --------------------------------------------------------------- # Lines 1277-1282: complete_apply — event_bus emit exception path # When event_bus.emit raises during complete_apply, the exception # is caught and the plan is still returned. # --------------------------------------------------------------- Scenario: complete_apply catches event bus emission failure Given a plan lifecycle service with a failing event bus for r2 And an action "local/apply-event-fail" exists for coverage boost r2 And a plan advanced to apply processing for coverage boost r2 When I complete apply on the plan and event bus emit fails Then the plan should still be in applied state # --------------------------------------------------------------- # Lines 1366-1378: cancel_plan — event_bus emit success path # Exercises the event_bus.emit call during cancel_plan. # --------------------------------------------------------------- Scenario: cancel_plan emits PLAN_CANCELLED event via event bus Given a plan lifecycle service with a recording event bus for r2 And an action "local/cancel-event" exists for coverage boost r2 And a plan created from "local/cancel-event" for coverage boost r2 When I cancel the plan with event bus recording Then the event bus should have recorded a PLAN_CANCELLED event # --------------------------------------------------------------- # Lines 1382-1388: cancel_plan — event_bus emit exception path # When event_bus.emit raises during cancel_plan, the exception # is caught and the plan is still returned. # --------------------------------------------------------------- Scenario: cancel_plan catches event bus emission failure Given a plan lifecycle service with a failing event bus for r2 And an action "local/cancel-event-fail" exists for coverage boost r2 And a plan created from "local/cancel-event-fail" for coverage boost r2 When I cancel the plan and event bus emit fails Then the plan should still be in cancelled state # --------------------------------------------------------------- # Lines 1417-1421: _cleanup_devcontainers — success path # When CleanupService.stop_active_devcontainers returns stopped IDs. # --------------------------------------------------------------- Scenario: cleanup devcontainers logs stopped containers on plan completion Given a plan lifecycle service with mocked devcontainer cleanup for r2 And an action "local/cleanup-ok" exists for coverage boost r2 And a plan advanced to apply processing for coverage boost r2 When I complete apply and devcontainer cleanup returns stopped containers Then the plan should be applied and cleanup should have been called # --------------------------------------------------------------- # Lines 1422-1426: _cleanup_devcontainers — exception path # When stop_active_devcontainers raises, the exception is caught. # --------------------------------------------------------------- Scenario: cleanup devcontainers catches exceptions without propagating Given a plan lifecycle service with failing devcontainer cleanup for r2 And an action "local/cleanup-fail" exists for coverage boost r2 And a plan advanced to apply processing for coverage boost r2 When I complete apply and devcontainer cleanup raises an exception Then the plan should still be applied despite cleanup failure