Feature: Consolidated Plan Model Lifecycle
  Combined scenarios from: plan_hierarchy_and_failure_handler, plan_lifecycle_helpers_coverage, plan_lifecycle_service_persistence_coverage, plan_lifecycle_transitions_r2, plan_model, plan_model_coverage, plan_model_uncovered_lines

  # ============================================================
  # Originally from: plan_hierarchy_and_failure_handler.feature
  # Feature: Plan Hierarchy and Subplan Failure Handling
  # ============================================================

  @subplan_hierarchy
  Scenario: A standalone plan is not considered a subplan
    Given a plan that was created independently
    Then the plan should not be recognized as a subplan


  @subplan_hierarchy
  Scenario: A plan spawned by another plan is a subplan
    Given a plan that was spawned by another plan
    Then the plan should be recognized as a subplan


  @subplan_hierarchy
  Scenario: A plan with no designated root is considered the root
    Given a plan with no designated root
    Then the plan should be recognized as a root plan


  @subplan_hierarchy
  Scenario: A plan whose root is itself is considered the root
    Given a plan whose designated root is itself
    Then the plan should be recognized as a root plan


  @subplan_hierarchy
  Scenario: A plan whose root is a different plan is not the root
    Given a plan whose designated root is a different plan
    Then the plan should not be recognized as a root plan


  @subplan_hierarchy
  Scenario: A root plan reports a depth of zero
    Given a plan with no designated root
    Then the plan hierarchy depth should be 0


  @subplan_hierarchy
  Scenario: A non-root plan reports a placeholder depth
    Given a plan whose designated root is a different plan
    Then the plan hierarchy depth should be -1


  @subplan_hierarchy
  Scenario: A plan with no child work has no subplans
    Given a plan that has no child work tracked
    Then the plan should report having no subplans


  @subplan_hierarchy
  Scenario: A plan with tracked child work has subplans
    Given a plan that has tracked child work
    Then the plan should report having subplans


  @failure_handler
  Scenario: The failure handler halts remaining work when fail-fast is enabled
    Given a subplan configuration with fail-fast enabled and parallel work
    And a subplan that has failed
    When the failure handler evaluates whether to halt remaining work
    Then the remaining work should be halted


  @failure_handler
  Scenario: The failure handler halts remaining work for sequential execution
    Given a subplan configuration with fail-fast disabled and sequential work
    And a subplan that has failed
    When the failure handler evaluates whether to halt remaining work
    Then the remaining work should be halted


  @failure_handler
  Scenario: The failure handler allows remaining work for parallel execution without fail-fast
    Given a subplan configuration with fail-fast disabled and parallel work
    And a subplan that has failed
    When the failure handler evaluates whether to halt remaining work
    Then the remaining work should continue


  @failure_handler
  Scenario: The failure handler allows remaining work for dependency-ordered execution without fail-fast
    Given a subplan configuration with fail-fast disabled and dependency-ordered work
    And a subplan that has failed
    When the failure handler evaluates whether to halt remaining work
    Then the remaining work should continue


  @failure_handler
  Scenario: The failure handler does not retry when retries are disabled
    Given a subplan configuration with retries disabled
    And a subplan that failed with error "ValidationError occurred"
    When the failure handler evaluates whether to retry the failed work
    Then the failed work should not be retried


  @failure_handler
  Scenario: The failure handler does not retry when all attempts are exhausted
    Given a subplan configuration allowing up to 2 retries
    And a subplan on attempt 3 that failed with error "TimeoutError"
    When the failure handler evaluates whether to retry the failed work
    Then the failed work should not be retried


  @failure_handler
  Scenario: A configuration error is not eligible for retry
    Given a subplan configuration allowing up to 3 retries
    And a subplan on attempt 1 that failed with error "ConfigurationError: bad config"
    When the failure handler evaluates whether to retry the failed work
    Then the failed work should not be retried


  @failure_handler
  Scenario: An authentication error is not eligible for retry
    Given a subplan configuration allowing up to 3 retries
    And a subplan on attempt 1 that failed with error "AuthenticationError: invalid token"
    When the failure handler evaluates whether to retry the failed work
    Then the failed work should not be retried


  @failure_handler
  Scenario: A missing resource error is not eligible for retry
    Given a subplan configuration allowing up to 3 retries
    And a subplan on attempt 1 that failed with error "MissingResourceError: file not found"
    When the failure handler evaluates whether to retry the failed work
    Then the failed work should not be retried


  @failure_handler
  Scenario: A circular dependency error is not eligible for retry
    Given a subplan configuration allowing up to 3 retries
    And a subplan on attempt 1 that failed with error "CircularDependencyError: cycle detected"
    When the failure handler evaluates whether to retry the failed work
    Then the failed work should not be retried


  @failure_handler
  Scenario: A validation error is eligible for retry
    Given a subplan configuration allowing up to 3 retries
    And a subplan on attempt 1 that failed with error "ValidationError: schema mismatch"
    When the failure handler evaluates whether to retry the failed work
    Then the failed work should be retried


  @failure_handler
  Scenario: A timeout error is eligible for retry
    Given a subplan configuration allowing up to 3 retries
    And a subplan on attempt 1 that failed with error "TimeoutError: deadline exceeded"
    When the failure handler evaluates whether to retry the failed work
    Then the failed work should be retried


  @failure_handler
  Scenario: A temporary resource error is eligible for retry
    Given a subplan configuration allowing up to 3 retries
    And a subplan on attempt 1 that failed with error "TemporaryResourceError: service unavailable"
    When the failure handler evaluates whether to retry the failed work
    Then the failed work should be retried


  @failure_handler
  Scenario: A merge conflict error is eligible for retry
    Given a subplan configuration allowing up to 3 retries
    And a subplan on attempt 1 that failed with error "MergeConflictError: conflicting changes"
    When the failure handler evaluates whether to retry the failed work
    Then the failed work should be retried


  @failure_handler
  Scenario: An unrecognized error type is not eligible for retry
    Given a subplan configuration allowing up to 3 retries
    And a subplan on attempt 1 that failed with error "SomeUnknownError: unexpected"
    When the failure handler evaluates whether to retry the failed work
    Then the failed work should not be retried


  @failure_handler
  Scenario: A failure with no error message is not eligible for retry
    Given a subplan configuration allowing up to 3 retries
    And a subplan on attempt 1 that failed with no error message
    When the failure handler evaluates whether to retry the failed work
    Then the failed work should not be retried


  # ============================================================
  # Originally from: plan_lifecycle_helpers_coverage.feature
  # Feature: Plan lifecycle helper coverage
  # ============================================================

  Scenario: Lifecycle service helper builds a plan lifecycle service
    When I call the plan lifecycle service helper
    Then the lifecycle service helper should return a plan lifecycle service


  # ============================================================
  # Originally from: plan_lifecycle_service_persistence_coverage.feature
  # Feature: PlanLifecycleService persistence fallback coverage
  # ============================================================

  Scenario: get_action falls back to persistence layer when not in memory
    Given a plan lifecycle service with a mock unit of work
    Given an action "local/db-only-action" exists only in the persistence layer
    When I call get_action with "local/db-only-action"
    Then the returned action should have namespaced name "local/db-only-action"
    And the action "local/db-only-action" should now be cached in memory


  Scenario: get_action_by_name falls back to persistence layer when not in memory
    Given a plan lifecycle service with a mock unit of work
    Given an action "local/db-only-named" exists only in the persistence layer for name lookup
    When I call get_action_by_name with "local/db-only-named"
    Then the returned action from name lookup should have namespaced name "local/db-only-named"
    And the action "local/db-only-named" should now be cached in memory after name lookup


  # ============================================================
  # Originally from: plan_lifecycle_transitions_r2.feature
  # Feature: PlanLifecycleService lifecycle transition branch coverage (round 2)
  # ============================================================

  Scenario: use_action on non-reusable action archives it after plan creation
    Given r2plc-a fresh plan lifecycle service with mock UoW
    Given r2plc-a non-reusable action "local/r2-oneshot" exists
    When r2plc-I use the non-reusable action to create a plan
    Then r2plc-the action "local/r2-oneshot" should be archived
    And r2plc-a plan should have been created from the action

    # -------------------------------------------------------------------
    # execute_plan persisted mode (line 216 True via _commit_plan)
    # -------------------------------------------------------------------


  Scenario: execute_plan transitions and persists via _commit_plan
    Given r2plc-a fresh plan lifecycle service with mock UoW
    Given r2plc-a plan in STRATEGIZE COMPLETE state
    When r2plc-I call execute_plan in persisted mode
    Then r2plc-the plan should be in EXECUTE phase
    And r2plc-the mock UoW should have received a plan update call

    # -------------------------------------------------------------------
    # apply_plan persisted mode (line 216 True via _commit_plan)
    # -------------------------------------------------------------------


  Scenario: apply_plan transitions and persists via _commit_plan
    Given r2plc-a fresh plan lifecycle service with mock UoW
    Given r2plc-a plan in EXECUTE COMPLETE state
    When r2plc-I call apply_plan in persisted mode
    Then r2plc-the plan should be in APPLY phase
    And r2plc-the mock UoW should have received a plan update call

    # -------------------------------------------------------------------
    # cancel_plan persisted mode (line 216 True via _commit_plan)
    # -------------------------------------------------------------------


  Scenario: cancel_plan persists cancellation via _commit_plan
    Given r2plc-a fresh plan lifecycle service with mock UoW
    Given r2plc-a plan in STRATEGIZE phase
    When r2plc-I cancel the plan with reason "user requested"
    Then r2plc-the plan processing state should be "cancelled"
    And r2plc-the mock UoW should have received a plan update call

    # -------------------------------------------------------------------
    # pause_plan and resume_plan persisted mode
    # -------------------------------------------------------------------


  Scenario: pause_plan persists via _commit_plan
    Given r2plc-a fresh plan lifecycle service with mock UoW
    Given r2plc-a plan in STRATEGIZE phase
    When r2plc-I pause the plan
    Then r2plc-the plan automation profile should be manual
    And r2plc-the mock UoW should have received a plan update call


  Scenario: resume_plan persists and auto-progresses via _commit_plan
    Given r2plc-a fresh plan lifecycle service with mock UoW
    Given r2plc-a plan in STRATEGIZE phase
    When r2plc-I resume the plan with profile "auto"
    Then r2plc-the plan automation profile should be "auto"


  # ============================================================
  # Originally from: plan_model.feature
  # Feature: Plan Domain Model
  # ============================================================

  Scenario: Parse simple name defaults to local namespace
    When I parse the namespaced name "my-action"
    Then the parsed namespace should be "local"
    And the parsed item name should be "my-action"
    And the parsed server should be empty


  Scenario: Parse name with explicit local namespace
    When I parse the namespaced name "local/my-action"
    Then the parsed namespace should be "local"
    And the parsed item name should be "my-action"


  Scenario: Parse name with organization namespace
    When I parse the namespaced name "myorg/my-action"
    Then the parsed namespace should be "myorg"
    And the parsed item name should be "my-action"


  Scenario: Parse name with server qualifier
    When I parse the namespaced name "prod:myorg/my-action"
    Then the parsed server should be "prod"
    And the parsed namespace should be "myorg"
    And the parsed item name should be "my-action"


  Scenario: NamespacedName string representation
    Given I have a namespaced name with server "prod" namespace "myorg" and name "my-action"
    Then the namespaced string representation should be "prod:myorg/my-action"


  Scenario: NamespacedName without server
    Given I have a namespaced name with namespace "local" and name "test-plan"
    Then the namespaced string representation should be "local/test-plan"


  Scenario: Invalid namespace with special characters fails
    When I try to create a namespaced name with namespace "my@org" and name "test"
    Then a validation error should be raised


  Scenario: Empty namespace defaults to local
    Given I create a namespaced name with an empty namespace and name "test-plan"
    Then the parsed namespace should be "local"

    # PlanPhase Tests


  Scenario: Plan phases are in correct order
    Then the plan phases should be in order "action, strategize, execute, apply"


  Scenario: STRATEGIZE phase is the starting phase
    Given I create a new plan
    Then the plan phase should be "strategize"

    # PlanState Tests


  Scenario: New plan starts in STRATEGIZE with QUEUED processing state
    Given I create a plan in strategize phase
    Then the plan phase should be "strategize"
    And the plan processing state should be "queued"


  Scenario: Strategize phase uses ProcessingState
    Given I create a plan in strategize phase
    Then the plan processing state should be "queued"


  Scenario: Plan in strategize phase defaults to QUEUED processing state
    Given I create a plan in strategize phase
    Then the plan processing state should be "queued"
    And the plan state should be "queued"


  Scenario: Strategize phase defaults processing_state to QUEUED
    Given I create a plan in strategize phase
    Then the plan processing state should be "queued"

    # Plan Identity Tests


  Scenario: Plan requires valid ULID
    When I try to create a plan identity with invalid ULID "not-a-ulid"
    Then a validation error should be raised


  Scenario: Plan identity with valid ULID succeeds
    When I create a plan identity with ULID "01ARZ3NDEKTSV4RRFFQ69G5FAV"
    Then the plan identity should be valid


  Scenario: Plan identity supports parent and root plan IDs
    When I create a plan identity with parent "01ARZ3NDEKTSV4RRFFQ69G5FAV" and root "01ARZ3NDEKTSV4RRFFQ69G5FAW"
    Then the parent plan ID should be "01ARZ3NDEKTSV4RRFFQ69G5FAV"
    And the root plan ID should be "01ARZ3NDEKTSV4RRFFQ69G5FAW"

    # Plan Lifecycle Tests


  Scenario: New plan starts in STRATEGIZE phase with QUEUED state
    Given I create a new plan with description "Test plan"
    Then the plan phase should be "strategize"
    And the plan processing state should be "queued"
    And the plan should not be terminal


  Scenario: Plan in STRATEGIZE with QUEUED cannot transition
    Given I create a plan in strategize phase
    Then the plan cannot transition to next phase


  Scenario: New plan in STRATEGIZE with QUEUED cannot transition
    Given I create a plan in strategize phase
    Then the plan cannot transition to next phase


  Scenario: Processing complete allows transition
    Given I create a plan in execute phase with complete processing state
    Then the plan can transition to next phase


  Scenario: Get next phase from STRATEGIZE is EXECUTE
    Given I create a new plan
    Then the next phase should be "execute"


  Scenario: Get next phase from APPLY is None (terminal phase)
    Given I create a plan in apply phase as terminal
    Then the next phase should be empty


  Scenario: Unknown phase returns no next phase
    Given I create a plan with an unknown phase value
    Then the next phase should be empty

    # Phase Transition Validation Tests


  Scenario: Valid transition from STRATEGIZE to EXECUTE
    Then transition from "strategize" to "execute" should be valid


  Scenario: Valid transition from EXECUTE to APPLY
    Then transition from "execute" to "apply" should be valid


  Scenario: Valid transition from APPLY to STRATEGIZE (revert via constrained)
    Then transition from "apply" to "strategize" should be valid


  Scenario: Invalid transition from STRATEGIZE to APPLY
    Then transition from "strategize" to "apply" should be invalid


  Scenario: Valid transition from ACTION to STRATEGIZE
    Then transition from "action" to "strategize" should be valid

    # Error State Tests


  Scenario: Plan in errored state is_errored returns True
    Given I create a plan in strategize phase with errored state
    Then the plan should be errored


  Scenario: Plan in processing state is_errored returns False
    Given I create a plan in strategize phase with processing state
    Then the plan should not be errored


  Scenario: Cancelled plan is terminal
    Given I create a plan in strategize phase with cancelled state
    Then the plan should be terminal

    # Model Validation Tests


  Scenario: Plan requires description
    When I try to create a plan without description
    Then a validation error should be raised


  Scenario: Plan description cannot be empty
    When I try to create a plan with empty description
    Then a validation error should be raised


  Scenario: Invalid phase value raises validation error
    When I try to create a plan with invalid phase value
    Then a validation error should be raised


  Scenario: Apply phase cannot transition to next phase
    Given I create a plan in apply phase as terminal
    Then the plan cannot transition to next phase


  # ============================================================
  # Originally from: plan_model_coverage.feature
  # Feature: Plan Model Coverage — New Fields and Helpers
  # ============================================================

  Scenario: Invalid name with special characters raises validation error
    When I try to create a namespaced name with namespace "local" and name "test@action"
    Then a validation error should be raised

    # ProjectLink.validate_alias classmethod


  Scenario: ProjectLink.validate_alias accepts a valid alias
    When I validate the project link alias "my-service"
    Then the alias should be valid


  Scenario: ProjectLink.validate_alias rejects an alias starting with a digit
    When I validate the project link alias "1bad-alias"
    Then the alias should be invalid


  Scenario: ProjectLink.validate_alias rejects an alias with uppercase
    When I validate the project link alias "BadAlias"
    Then the alias should be invalid


  Scenario: ProjectLink.validate_alias rejects an empty alias
    When I validate an empty project link alias
    Then the alias should be invalid

    # ProjectLink field validator — invalid alias on construction


  Scenario: Creating a ProjectLink with an invalid alias raises validation error
    When I try to create a project link with alias "INVALID!"
    Then a validation error should be raised


  Scenario: Creating a ProjectLink with a valid alias succeeds
    When I create a project link with alias "api-svc"
    Then the project link alias should be "api-svc"

    # Plan — APPLY phase with APPLIED processing_state is terminal


  Scenario: APPLY phase with APPLIED processing state is terminal
    When I create a plan in apply phase with applied processing state
    Then the plan processing state should be "applied"
    And the plan should be terminal

    # Plan — duplicate project link alias uniqueness


  Scenario: Duplicate project link aliases raise validation error
    When I try to create a plan with duplicate project link aliases
    Then a validation error should be raised


  Scenario: Distinct project link aliases are accepted
    When I create a plan with distinct project link aliases
    Then the plan should have 2 project links

    # Plan.as_cli_dict — base fields


  Scenario: as_cli_dict includes base identification fields
    Given I create a plan for CLI output
    When I call as_cli_dict
    Then the CLI dict should contain key "plan_id"
    And the CLI dict should contain key "name"
    And the CLI dict should contain key "action"
    And the CLI dict should contain key "phase"
    And the CLI dict should contain key "state"
    And the CLI dict should contain key "description"
    And the CLI dict should contain key "created_at"
    And the CLI dict should contain key "updated_at"

    # Plan.as_cli_dict — definition_of_done


  Scenario: as_cli_dict includes definition_of_done when set
    Given I create a plan with definition of done "all tests pass"
    When I call as_cli_dict
    Then the CLI dict key "definition_of_done" should be "all tests pass"


  Scenario: as_cli_dict omits definition_of_done when not set
    Given I create a plan for CLI output
    When I call as_cli_dict
    Then the CLI dict should not contain key "definition_of_done"

    # Plan.as_cli_dict — automation profile provenance


  Scenario: as_cli_dict includes automation profile with provenance
    Given I create a plan with automation profile "trusted" from "action"
    When I call as_cli_dict
    Then the CLI dict key "automation_profile" should be "trusted"
    And the CLI dict key "automation_profile_source" should be "action"


  Scenario: as_cli_dict omits automation profile when not set
    Given I create a plan for CLI output
    When I call as_cli_dict
    Then the CLI dict should not contain key "automation_profile"

    # Plan.as_cli_dict — project links


  Scenario: as_cli_dict renders project links with alias and read_only
    Given I create a plan with project links
    When I call as_cli_dict
    Then the CLI dict key "projects" should be a list of length 2


  Scenario: as_cli_dict omits projects when none are linked
    Given I create a plan for CLI output
    When I call as_cli_dict
    Then the CLI dict should not contain key "projects"

    # Plan.as_cli_dict — invariants


  Scenario: as_cli_dict renders invariants with source tags
    Given I create a plan with invariants
    When I call as_cli_dict
    Then the CLI dict key "invariants" should be a list of length 2


  Scenario: as_cli_dict omits invariants when empty
    Given I create a plan for CLI output
    When I call as_cli_dict
    Then the CLI dict should not contain key "invariants"

    # Plan.as_cli_dict — arguments


  Scenario: as_cli_dict renders arguments in stable order
    Given I create a plan with arguments
    When I call as_cli_dict
    Then the CLI dict should contain key "arguments"
    And the CLI dict arguments should preserve order


  Scenario: as_cli_dict omits arguments when empty
    Given I create a plan for CLI output
    When I call as_cli_dict
    Then the CLI dict should not contain key "arguments"

    # Plan.as_cli_dict — actor fields


  Scenario: as_cli_dict includes strategy_actor when set
    Given I create a plan with strategy actor "local/planner"
    When I call as_cli_dict
    Then the CLI dict key "strategy_actor" should be "local/planner"


  Scenario: as_cli_dict includes execution_actor when set
    Given I create a plan with execution actor "local/coder"
    When I call as_cli_dict
    Then the CLI dict key "execution_actor" should be "local/coder"


  Scenario: as_cli_dict omits actor fields when not set
    Given I create a plan for CLI output
    When I call as_cli_dict
    Then the CLI dict should not contain key "strategy_actor"
    And the CLI dict should not contain key "execution_actor"

    # Plan.as_cli_dict — error message


  Scenario: as_cli_dict includes error when present
    Given I create a plan with error message "sandbox timeout"
    When I call as_cli_dict
    Then the CLI dict key "error" should be "sandbox timeout"


  Scenario: as_cli_dict omits error when not present
    Given I create a plan for CLI output
    When I call as_cli_dict
    Then the CLI dict should not contain key "error"

    # Plan.as_cli_dict — parent plan and subplan count


  Scenario: as_cli_dict includes parent_plan_id for subplans
    Given I create a subplan for CLI output
    When I call as_cli_dict
    Then the CLI dict should contain key "parent_plan_id"


  Scenario: as_cli_dict includes subplan_count when subplans exist
    Given I create a plan with subplan statuses
    When I call as_cli_dict
    Then the CLI dict key "subplan_count" should be 1


  Scenario: as_cli_dict omits parent and subplan fields for root plan
    Given I create a plan for CLI output
    When I call as_cli_dict
    Then the CLI dict should not contain key "parent_plan_id"
    And the CLI dict should not contain key "subplan_count"

    # ---- is_subplan / is_root_plan / depth properties ----


  Scenario: Root plan is not a subplan and has depth zero
    Given I create a plan for CLI output
    Then the plan should not be a subplan
    And the plan should be a root plan
    And the plan depth should be 0


  Scenario: Child plan is a subplan and has depth minus one
    Given I create a child plan with a parent
    Then the plan should be a subplan
    And the plan should not be a root plan
    And the plan depth should be -1

    # ---- SubplanFailureHandler.should_stop_others ----


  Scenario: Failure handler stops others when fail_fast is true
    Given a subplan config with fail_fast enabled and sequential mode
    And a failed subplan status
    When I check should_stop_others
    Then should_stop_others should be true


  Scenario: Failure handler stops others in sequential mode
    Given a subplan config with fail_fast disabled and sequential mode
    And a failed subplan status
    When I check should_stop_others
    Then should_stop_others should be true


  Scenario: Failure handler does not stop others in parallel mode without fail_fast
    Given a subplan config with fail_fast disabled and parallel mode
    And a failed subplan status
    When I check should_stop_others
    Then should_stop_others should be false

    # ---- SubplanFailureHandler.should_retry ----


  Scenario: Failure handler does not retry when retry_failed is false
    Given a subplan config with retry disabled
    And a failed subplan status with error "TimeoutError"
    When I check should_retry
    Then should_retry should be false


  Scenario: Failure handler does not retry when max retries exceeded
    Given a subplan config with max retries 1
    And a failed subplan status on attempt 2 with error "TimeoutError"
    When I check should_retry
    Then should_retry should be false


  Scenario: Failure handler retries retriable failure within limit
    Given a subplan config with retry enabled and max retries 2
    And a failed subplan status on attempt 1 with error "TimeoutError"
    When I check should_retry
    Then should_retry should be true


  Scenario: Failure handler does not retry non-retriable error
    Given a subplan config with retry enabled and max retries 2
    And a failed subplan status on attempt 1 with error "ConfigurationError"
    When I check should_retry
    Then should_retry should be false


  Scenario: Failure handler does not retry unknown error
    Given a subplan config with retry enabled and max retries 2
    And a failed subplan status on attempt 1 with error "SomeUnknownError"
    When I check should_retry
    Then should_retry should be false


  # ============================================================
  # Originally from: plan_model_uncovered_lines.feature
  # Feature: Plan Hierarchy and Subplan Failure Handling
  # ============================================================

  @subplan_hierarchy
  Scenario: A standalone plan is not considered a subplan
    Given an uncovered-lines plan that was created independently
    Then the uncovered-lines plan should not be recognized as a subplan


  @subplan_hierarchy
  Scenario: A plan spawned by another plan is a subplan
    Given an uncovered-lines plan that was spawned by another plan
    Then the uncovered-lines plan should be recognized as a subplan


  @subplan_hierarchy
  Scenario: A plan with no designated root is considered the root
    Given an uncovered-lines plan with no designated root
    Then the uncovered-lines plan should be recognized as a root plan


  @subplan_hierarchy
  Scenario: A plan whose root is itself is considered the root
    Given an uncovered-lines plan whose designated root is itself
    Then the uncovered-lines plan should be recognized as a root plan


  @subplan_hierarchy
  Scenario: A plan whose root is a different plan is not the root
    Given an uncovered-lines plan whose designated root is a different plan
    Then the uncovered-lines plan should not be recognized as a root plan


  @subplan_hierarchy
  Scenario: A root plan reports a depth of zero
    Given an uncovered-lines plan with no designated root
    Then the uncovered-lines plan hierarchy depth should be 0


  @subplan_hierarchy
  Scenario: A non-root plan reports a placeholder depth
    Given an uncovered-lines plan whose designated root is a different plan
    Then the uncovered-lines plan hierarchy depth should be -1


  @subplan_hierarchy
  Scenario: A plan with no child work has no subplans
    Given an uncovered-lines plan that has no child work tracked
    Then the uncovered-lines plan should report having no subplans


  @subplan_hierarchy
  Scenario: A plan with tracked child work has subplans
    Given an uncovered-lines plan that has tracked child work
    Then the uncovered-lines plan should report having subplans


  @failure_handler
  Scenario: The failure handler halts remaining work when fail-fast is enabled
    Given an uncovered-lines subplan configuration with fail-fast enabled and parallel work
    And an uncovered-lines subplan that has failed
    When the uncovered-lines failure handler evaluates whether to halt remaining work
    Then the uncovered-lines remaining work should be halted


  @failure_handler
  Scenario: The failure handler halts remaining work for sequential execution
    Given an uncovered-lines subplan configuration with fail-fast disabled and sequential work
    And an uncovered-lines subplan that has failed
    When the uncovered-lines failure handler evaluates whether to halt remaining work
    Then the uncovered-lines remaining work should be halted


  @failure_handler
  Scenario: The failure handler allows remaining work for parallel execution without fail-fast
    Given an uncovered-lines subplan configuration with fail-fast disabled and parallel work
    And an uncovered-lines subplan that has failed
    When the uncovered-lines failure handler evaluates whether to halt remaining work
    Then the uncovered-lines remaining work should continue


  @failure_handler
  Scenario: The failure handler allows remaining work for dependency-ordered execution without fail-fast
    Given an uncovered-lines subplan configuration with fail-fast disabled and dependency-ordered work
    And an uncovered-lines subplan that has failed
    When the uncovered-lines failure handler evaluates whether to halt remaining work
    Then the uncovered-lines remaining work should continue


  @failure_handler
  Scenario: The failure handler does not retry when retries are disabled
    Given an uncovered-lines subplan configuration with retries disabled
    And an uncovered-lines subplan that failed with error "ValidationError occurred"
    When the uncovered-lines failure handler evaluates whether to retry the failed work
    Then the uncovered-lines failed work should not be retried


  @failure_handler
  Scenario: The failure handler does not retry when all attempts are exhausted
    Given an uncovered-lines subplan configuration allowing up to 2 retries
    And an uncovered-lines subplan on attempt 3 that failed with error "TimeoutError"
    When the uncovered-lines failure handler evaluates whether to retry the failed work
    Then the uncovered-lines failed work should not be retried


  @failure_handler
  Scenario: A configuration error is not eligible for retry
    Given an uncovered-lines subplan configuration allowing up to 3 retries
    And an uncovered-lines subplan on attempt 1 that failed with error "ConfigurationError: bad config"
    When the uncovered-lines failure handler evaluates whether to retry the failed work
    Then the uncovered-lines failed work should not be retried


  @failure_handler
  Scenario: An authentication error is not eligible for retry
    Given an uncovered-lines subplan configuration allowing up to 3 retries
    And an uncovered-lines subplan on attempt 1 that failed with error "AuthenticationError: invalid token"
    When the uncovered-lines failure handler evaluates whether to retry the failed work
    Then the uncovered-lines failed work should not be retried


  @failure_handler
  Scenario: A missing resource error is not eligible for retry
    Given an uncovered-lines subplan configuration allowing up to 3 retries
    And an uncovered-lines subplan on attempt 1 that failed with error "MissingResourceError: file not found"
    When the uncovered-lines failure handler evaluates whether to retry the failed work
    Then the uncovered-lines failed work should not be retried


  @failure_handler
  Scenario: A circular dependency error is not eligible for retry
    Given an uncovered-lines subplan configuration allowing up to 3 retries
    And an uncovered-lines subplan on attempt 1 that failed with error "CircularDependencyError: cycle detected"
    When the uncovered-lines failure handler evaluates whether to retry the failed work
    Then the uncovered-lines failed work should not be retried


  @failure_handler
  Scenario: A validation error is eligible for retry
    Given an uncovered-lines subplan configuration allowing up to 3 retries
    And an uncovered-lines subplan on attempt 1 that failed with error "ValidationError: schema mismatch"
    When the uncovered-lines failure handler evaluates whether to retry the failed work
    Then the uncovered-lines failed work should be retried


  @failure_handler
  Scenario: A timeout error is eligible for retry
    Given an uncovered-lines subplan configuration allowing up to 3 retries
    And an uncovered-lines subplan on attempt 1 that failed with error "TimeoutError: deadline exceeded"
    When the uncovered-lines failure handler evaluates whether to retry the failed work
    Then the uncovered-lines failed work should be retried


  @failure_handler
  Scenario: A temporary resource error is eligible for retry
    Given an uncovered-lines subplan configuration allowing up to 3 retries
    And an uncovered-lines subplan on attempt 1 that failed with error "TemporaryResourceError: service unavailable"
    When the uncovered-lines failure handler evaluates whether to retry the failed work
    Then the uncovered-lines failed work should be retried


  @failure_handler
  Scenario: A merge conflict error is eligible for retry
    Given an uncovered-lines subplan configuration allowing up to 3 retries
    And an uncovered-lines subplan on attempt 1 that failed with error "MergeConflictError: conflicting changes"
    When the uncovered-lines failure handler evaluates whether to retry the failed work
    Then the uncovered-lines failed work should be retried


  @failure_handler
  Scenario: An unrecognized error type is not eligible for retry
    Given an uncovered-lines subplan configuration allowing up to 3 retries
    And an uncovered-lines subplan on attempt 1 that failed with error "SomeUnknownError: unexpected"
    When the uncovered-lines failure handler evaluates whether to retry the failed work
    Then the uncovered-lines failed work should not be retried


  @failure_handler
  Scenario: A failure with no error message is not eligible for retry
    Given an uncovered-lines subplan configuration allowing up to 3 retries
    And an uncovered-lines subplan on attempt 1 that failed with no error message
    When the uncovered-lines failure handler evaluates whether to retry the failed work
    Then the uncovered-lines failed work should not be retried

