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
