Feature: PlanLifecycleService error and persistence branch coverage (round 2)
  As a developer maintaining PlanLifecycleService
  I want every partial branch fully exercised
  So that plan_lifecycle_service.py branch coverage reaches 100%

  # Targets the following partial branches:
  #   Line 100  – InvalidPhaseTransitionError.__init__ `if not message:` False branch
  #   Line 216  – _commit_plan `if self._persisted …` True branch (via mock UoW)
  #   Line 327  – create_action `if self._persisted …` True branch
  #   Line 364  – get_action `if self._persisted …` True branch (not-found fallback)
  #   Line 461  – archive_action `if self._persisted …` True branch
  #   Line 570  – use_action `if self._persisted …` True branch
  #   Line 607  – get_plan `if self._persisted …` True branch (not-found fallback)

  # -------------------------------------------------------------------
  # In-memory mode (no UoW) – validates False side of _persisted checks
  # -------------------------------------------------------------------

  Background:
    Given r2plc-a fresh plan lifecycle service with mock UoW

  # -------------------------------------------------------------------
  # InvalidPhaseTransitionError with custom message (line 100 False)
  # -------------------------------------------------------------------

  Scenario: InvalidPhaseTransitionError raised with explicit custom message
    When r2plc-I construct InvalidPhaseTransitionError with a custom message
    Then r2plc-the error message should be the custom message
    And r2plc-the from_phase should be STRATEGIZE
    And r2plc-the to_phase should be APPLY

  Scenario: InvalidPhaseTransitionError raised with default message
    When r2plc-I construct InvalidPhaseTransitionError without a message
    Then r2plc-the error message should contain "Invalid phase transition"
    And r2plc-the from_phase should be STRATEGIZE
    And r2plc-the to_phase should be EXECUTE

  Scenario: revert_plan raises InvalidPhaseTransitionError with custom message
    Given r2plc-a plan in STRATEGIZE phase
    When r2plc-I attempt to revert the plan to APPLY phase
    Then r2plc-an InvalidPhaseTransitionError should have been raised
    And r2plc-the caught error message should contain "Cannot revert"

  # -------------------------------------------------------------------
  # _commit_plan in persisted mode (line 216 True)
  # -------------------------------------------------------------------

  Scenario: _commit_plan persists via UoW when persisted mode is active
    Given r2plc-a plan in STRATEGIZE phase
    When r2plc-I start strategize on the plan
    Then r2plc-the mock UoW should have received a plan update call

  Scenario: fail_strategize commits plan via persisted _commit_plan
    Given r2plc-a plan in STRATEGIZE PROCESSING state
    When r2plc-I fail the strategize with error "something broke"
    Then r2plc-the mock UoW should have received a plan update call
    And r2plc-the plan processing state should be "errored"

  # -------------------------------------------------------------------
  # create_action persisted mode (line 327 True)
  # -------------------------------------------------------------------

  Scenario: create_action persists via UoW when persisted
    When r2plc-I create an action "local/r2-persist-test" in persisted mode
    Then r2plc-the mock UoW should have received an action create call
    And r2plc-the action should also be in the in-memory cache

  # -------------------------------------------------------------------
  # use_action persisted mode (line 570 True)
  # -------------------------------------------------------------------

  Scenario: use_action persists the new plan via UoW
    Given r2plc-an action "local/r2-use-persist" exists
    When r2plc-I use the action to create a plan in persisted mode
    Then r2plc-the mock UoW should have received a plan create call
    And r2plc-the plan should also be in the in-memory plan cache

  # -------------------------------------------------------------------
  # archive_action persisted mode (line 461 True)
  # -------------------------------------------------------------------

  Scenario: archive_action persists via UoW when persisted
    Given r2plc-an action "local/r2-archive-persist" exists
    When r2plc-I archive the action "local/r2-archive-persist" in persisted mode
    Then r2plc-the mock UoW should have received an action update call
    And r2plc-the action state should be archived

  # -------------------------------------------------------------------
  # get_action persistence fallback returns None (line 364-370)
  # -------------------------------------------------------------------

  Scenario: get_action raises NotFoundError when persistence also returns None
    When r2plc-I attempt to get action "local/nonexistent-r2" in persisted mode
    Then r2plc-a NotFoundError should have been raised for action

  # -------------------------------------------------------------------
  # get_plan persistence fallback returns None (line 607-613)
  # -------------------------------------------------------------------

  Scenario: get_plan raises NotFoundError when persistence also returns None
    When r2plc-I attempt to get plan "01ZZZZZZZZZZZZZZZZZZZZZZZZ" in persisted mode
    Then r2plc-a NotFoundError should have been raised for plan

  # -------------------------------------------------------------------
  # update_error_details in persisted mode (hits _commit_plan True)
  # -------------------------------------------------------------------

  Scenario: update_error_details merges details and persists
    Given r2plc-a plan in STRATEGIZE phase
    When r2plc-I update error details with key "reason" value "timeout"
    Then r2plc-the plan error_details should contain key "reason"
    And r2plc-the mock UoW should have received a plan update call

  Scenario: update_error_details merges into existing error_details
    Given r2plc-a plan in STRATEGIZE phase with existing error_details
    When r2plc-I update error details with key "extra" value "info"
    Then r2plc-the plan error_details should contain key "extra"
    And r2plc-the plan error_details should contain key "original"
