Feature: Plan Lifecycle Service Coverage R3
  Additional coverage for PlanLifecycleService uncovered lines including
  estimation exception handling, list_actions persistence paths,
  list_plans cache refresh, _complete_apply_if_queued branches,
  and try_auto_run full lifecycle progression.

  Background:
    Given plscov3 a fresh service is ready

  # ── _run_estimation exception handler (lines 318-323) ──

  Scenario: Estimation actor failure is logged and swallowed
    Given plscov3 an action with estimation actor exists named "local/est-fail" actor "est-actor"
    And plscov3 the action "local/est-fail" is used on project "proj"
    And plscov3 the current plan is advanced to Strategize COMPLETE
    When plscov3 execute_plan is invoked with estimation stub raising
    Then plscov3 the current plan should be in Execute phase

  # ── _resolve_actor_registry_entry dunder prefix (line 452) ──

  Scenario: Actor registry entry with dunder prefix returns None
    When plscov3 resolve_actor_registry_entry is invoked for "__internal__"
    Then plscov3 the resolved actor entry is None

  # ── list_actions with persistence - namespace filter (lines 640-645) ──

  Scenario: list_actions queries DB with namespace filter
    Given plscov3 a service with mock UoW is ready
    When plscov3 list_actions is invoked with namespace "local" and state "available"
    Then plscov3 the mock get_by_namespace was invoked with "local"

  # ── list_actions with persistence - no namespace filter (line 648) ──

  Scenario: list_actions queries DB without namespace uses list_all
    Given plscov3 a service with mock UoW is ready
    When plscov3 list_actions is invoked without any namespace
    Then plscov3 the mock actions list_all was invoked

  # ── list_actions persistence - cache refresh (lines 650-653) ──

  Scenario: list_actions refreshes in-memory cache from DB results
    Given plscov3 a service with mock UoW returning DB actions is ready
    When plscov3 list_actions is invoked filtering by namespace "local"
    Then plscov3 the actions in-memory cache has the DB action

  # ── list_actions persistence - state filter on list_all (lines 655-656) ──

  Scenario: list_actions applies state filter after list_all
    Given plscov3 a service with mock UoW returning mixed-state actions is ready
    When plscov3 list_actions is invoked without namespace but with state "available"
    Then plscov3 only actions in available state are returned

  # ── list_actions persistence - DatabaseError fallback (lines 658-659) ──

  Scenario: list_actions falls back to in-memory on DatabaseError
    Given plscov3 a service with failing DB actions is ready
    And plscov3 an in-memory action "local/fallback" is added
    When plscov3 list_actions is invoked expecting DB fallback
    Then plscov3 the fallback in-memory action is returned

  # ── list_plans persisted path cache refresh (line 917) ──

  Scenario: list_plans refreshes in-memory cache from DB
    Given plscov3 a service with mock UoW returning DB plans is ready
    When plscov3 list_plans is invoked
    Then plscov3 the plans in-memory cache was refreshed

  # ── _complete_apply_if_queued - not in Apply phase (line 1592) ──

  Scenario: _complete_apply_if_queued returns early when not in Apply phase
    Given plscov3 a basic action named "local/not-apply" is created
    And plscov3 the action "local/not-apply" is used on project "proj"
    When plscov3 complete_apply_if_queued is invoked
    Then plscov3 the current plan phase remains Strategize

  # ── _complete_apply_if_queued - not QUEUED (line 1594) ──

  Scenario: _complete_apply_if_queued returns early when not QUEUED
    Given plscov3 a basic action named "local/not-queued" is created
    And plscov3 the action "local/not-queued" is used on project "proj"
    And plscov3 the current plan is advanced to Apply PROCESSING
    When plscov3 complete_apply_if_queued is invoked
    Then plscov3 the current plan remains in Apply PROCESSING

  # ── _complete_apply_if_queued - async enabled (lines 1599-1603) ──

  Scenario: _complete_apply_if_queued skips inline when async enabled
    Given plscov3 an async-enabled service with job store is ready
    And plscov3 a basic action named "local/async-apply" is created
    And plscov3 the action "local/async-apply" is used on project "proj"
    And plscov3 the current plan is advanced to Apply QUEUED
    When plscov3 complete_apply_if_queued is invoked
    Then plscov3 the current plan remains in Apply QUEUED

  # ── _complete_apply_if_queued - exception path (lines 1608-1614) ──

  Scenario: _complete_apply_if_queued catches exception and fails apply
    Given plscov3 a basic action named "local/apply-err" is created
    And plscov3 the action "local/apply-err" is used on project "proj"
    And plscov3 the current plan is advanced to Apply QUEUED
    When plscov3 complete_apply_if_queued is invoked with start_apply raising
    Then plscov3 the current plan processing state is ERRORED

  # ── try_auto_run - terminal plan (lines 1687-1690) ──

  Scenario: try_auto_run returns immediately for terminal plan
    Given plscov3 a basic action named "local/terminal" is created
    And plscov3 the action "local/terminal" is used on project "proj"
    And plscov3 the current plan is forced to CANCELLED state
    When plscov3 try_auto_run is invoked
    Then plscov3 the current plan is still CANCELLED

  # ── try_auto_run - full auto-run through all phases (lines 1697-1741) ──

  Scenario: try_auto_run drives plan through all phases with CI profile
    Given plscov3 an action with ci automation profile named "local/full-auto" is created
    And plscov3 that profiled action "local/full-auto" is used on project "proj" with profile "ci"
    When plscov3 try_auto_run is invoked
    Then plscov3 the current plan has reached terminal APPLIED

  # ── try_auto_run - strategize only (lines 1697-1709) ──

  Scenario: try_auto_run runs strategize phase only when execute gated
    Given plscov3 an action with supervised automation profile named "local/strat-only" is created
    And plscov3 that profiled action "local/strat-only" is used on project "proj" with profile "supervised"
    When plscov3 try_auto_run is invoked
    Then plscov3 the current plan is in Strategize COMPLETE
