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