Feature: Plan CLI coverage boost round 2 - remaining uncovered lines
  As a developer
  I want to exercise the remaining uncovered code paths in plan.py
  So that code coverage improves for the plan CLI module

  # ===================================================================
  # _plan_spec_dict: execution_env_priority fallback (line 153)
  # ===================================================================

  Scenario: _plan_spec_dict uses FALLBACK when execution_env_priority is None
    Given a v3 plan with execution_environment "host" and execution_env_priority None
    When I call _plan_spec_dict for r2 coverage
    Then the r2 spec dict should contain "execution_environment" with value "host"
    And the r2 spec dict should contain "execution_env_priority" with value "fallback"

  # ===================================================================
  # apply command v3 lifecycle path: plan_id provided (lines 785-786)
  # _apply_with_id happy path (lines 876-925)
  # ===================================================================

  Scenario: apply command delegates to _apply_with_id when plan_id is given
    Given a r2boost CLI runner
    And a mocked lifecycle service for r2boost apply happy path
    When I invoke r2boost apply with plan_id in rich format
    Then the r2boost command should exit normally
    And the r2boost output should contain "Plan Applied"

  Scenario: apply command with plan_id outputs JSON format
    Given a r2boost CLI runner
    And a mocked lifecycle service for r2boost apply happy path
    When I invoke r2boost apply with plan_id and format json
    Then the r2boost command should exit normally
    And the r2boost output should contain "plan_id"

  # ===================================================================
  # _apply_with_id: plan not found (lines 886-888)
  # ===================================================================

  Scenario: _apply_with_id aborts when plan is not found
    Given a r2boost CLI runner
    And a mocked lifecycle service for r2boost apply where plan is not found
    When I invoke r2boost apply with plan_id in rich format
    Then the r2boost command should abort
    And the r2boost output should contain "not found"

  # ===================================================================
  # _apply_with_id: plan is read-only (lines 889-893)
  # ===================================================================

  Scenario: _apply_with_id aborts when plan is read-only
    Given a r2boost CLI runner
    And a mocked lifecycle service for r2boost apply where plan is read-only
    When I invoke r2boost apply with plan_id in rich format
    Then the r2boost command should abort
    And the r2boost output should contain "read-only"

  # ===================================================================
  # _apply_with_id: InvalidPhaseTransitionError (lines 927-929)
  # ===================================================================

  Scenario: _apply_with_id handles InvalidPhaseTransitionError
    Given a r2boost CLI runner
    And a mocked lifecycle service for r2boost apply that raises InvalidPhaseTransitionError
    When I invoke r2boost apply with plan_id in rich format
    Then the r2boost command should abort
    And the r2boost output should contain "Invalid transition"

  # ===================================================================
  # _apply_with_id: PlanNotReadyError (lines 930-932)
  # ===================================================================

  Scenario: _apply_with_id handles PlanNotReadyError
    Given a r2boost CLI runner
    And a mocked lifecycle service for r2boost apply that raises PlanNotReadyError
    When I invoke r2boost apply with plan_id in rich format
    Then the r2boost command should abort
    And the r2boost output should contain "Plan not ready"

  # ===================================================================
  # _apply_with_id: ValueError (lines 933-937)
  # ===================================================================

  Scenario: _apply_with_id handles ValueError
    Given a r2boost CLI runner
    And a mocked lifecycle service for r2boost apply that raises ValueError
    When I invoke r2boost apply with plan_id in rich format
    Then the r2boost command should abort
    And the r2boost output should contain "Execution Error"

  # ===================================================================
  # _apply_with_id: CleverAgentsError (lines 938-940)
  # ===================================================================

  Scenario: _apply_with_id handles CleverAgentsError
    Given a r2boost CLI runner
    And a mocked lifecycle service for r2boost apply that raises CleverAgentsError
    When I invoke r2boost apply with plan_id in rich format
    Then the r2boost command should abort
    And the r2boost output should contain "Error"

  # ===================================================================
  # _get_plan_executor: lifecycle_service=None fallback (line 1249)
  # ===================================================================

  Scenario: _get_plan_executor calls _get_lifecycle_service when not provided
    Given a mocked container for r2boost plan executor
    When I call _get_plan_executor without lifecycle_service
    Then the r2boost plan executor should be returned

  # ===================================================================
  # execute_plan: plan not found after phase checking (lines 1838-1839)
  # ===================================================================

  Scenario: execute_plan aborts when plan not found after phase check
    Given a r2boost CLI runner
    And a mocked lifecycle service for r2boost execute where plan vanishes
    When I invoke r2boost execute with plan_id
    Then the r2boost command should abort
    And the r2boost output should contain "not found"

  # ===================================================================
  # execute_plan: PreflightRejection handler (lines 1898-1899)
  # ===================================================================

  Scenario: execute_plan handles PreflightRejection
    Given a r2boost CLI runner
    And a mocked lifecycle service for r2boost execute that raises PreflightRejection
    When I invoke r2boost execute with plan_id
    Then the r2boost command should abort
    And the r2boost output should contain "Pre-flight check failed"

  # ===================================================================
  # execute_plan: ValueError handler (lines 1910-1911)
  # ===================================================================

  Scenario: execute_plan handles ValueError from provider resolution
    Given a r2boost CLI runner
    And a mocked lifecycle service for r2boost execute that raises ValueError
    When I invoke r2boost execute with plan_id
    Then the r2boost command should abort
    And the r2boost output should contain "Execution Error"

  # ===================================================================
  # resume_plan: rich output with no decision_id, no checkpoint, no sandbox
  # (lines 2904, 2909, 2914 - the else "" branches)
  # ===================================================================

  Scenario: resume_plan rich output with all optional fields as None
    Given a r2boost CLI runner
    And a mocked resume service for r2boost with no optional fields
    When I invoke r2boost plan resume in rich format
    Then the r2boost command should exit normally
    And the r2boost output should contain "Resume Summary"
    And the r2boost output should not contain "Decision ID"
    And the r2boost output should not contain "Checkpoint"
    And the r2boost output should not contain "Sandbox"

  # ===================================================================
  # tree_decisions_cmd: TABLE format with show_superseded (line 3299)
  # ===================================================================

  Scenario: tree command in table format shows all decisions including superseded
    Given a r2boost CLI runner
    And a mocked decision service for r2boost tree with superseded decisions
    When I invoke r2boost tree in table format with show-superseded
    Then the r2boost command should exit normally
    And the r2boost output should contain "Decision Tree"

  # ===================================================================
  # tree_decisions_cmd: TABLE format long chosen_option truncation (line 3331)
  # ===================================================================

  Scenario: tree command in table format truncates long chosen_option
    Given a r2boost CLI runner
    And a mocked decision service for r2boost tree with long chosen option
    When I invoke r2boost tree in table format
    Then the r2boost command should exit normally
    And the r2boost output should contain "Decision Tree"
