@tdd @tdd_issue @tdd_issue_10938 @tier-hydration
Feature: Tier hydrator integration in PlanExecutor run_strategize (#10938)
  Verifies that PlanExecutor.run_strategize correctly:
  - Calls hydrate_tiers_for_plan when tier_service, project_repository, and
    resource_registry are all wired
  - Skips hydration if this plan_id has already been hydrated by this executor
    instance (plan-id-scoped cache, prevents cross-plan contamination)
  - Catches hydration failures without aborting the strategize phase

  Forgejo: #10938


# -------------------------------------------------------------------
  # Success — hydrate_tiers_for_plan is called when all dependencies exist
  # -------------------------------------------------------------------

  Scenario: Hydration is invoked when tier_service, project_repository and resource_registry are present
    Given a mock PlanExecutor with tier_service, project_repository and resource_registry wired in
    And a plan in the Strategize phase
    When I call run_strategize on that PlanExecutor
    Then hydrate_tiers_for_plan should have been called once
    And the plan executor strategize result should be a valid run_strategize response


# -------------------------------------------------------------------
  # Cache — skip already-hydrated tiers (new block from PR #10938)
  # -------------------------------------------------------------------

  Scenario: Hydration is skipped when plan_id has already been hydrated by this executor
    Given a mock PlanExecutor with tier_service and plan_id already marked as hydrated
    And a plan in the Strategize phase
    When I call run_strategize on that PlanExecutor
    Then hydrate_tiers_for_plan should not have been called because the plan was already hydrated
    And the plan executor strategize result should be a valid run_strategize response

  Scenario: Hydration runs when hot tier is empty
    Given a mock PlanExecutor with tier_service but no pre-existing hot fragments
    And a plan in the Strategize phase
    When I call run_strategize on that PlanExecutor
    Then hydrate_tiers_for_plan should have been called once


# -------------------------------------------------------------------
  # Failure — hydration failure does not block strategize (new try/except from PR #10938)
  # -------------------------------------------------------------------

  Scenario: Hydration OSError is caught non-fatally and strategize continues
    Given a mock PlanExecutor with tier_service, project_repository and resource_registry where hydrate fails with OSError
    And a plan in the Strategize phase
    When I call run_strategize on that PlanExecutor
    Then hydrate_tiers_for_plan should have been called once
    Then the strategy result should contain decisions (strategize succeeded despite hydration failure)


# -------------------------------------------------------------------
  # No-op — tier_service not wired does not crash
  # -------------------------------------------------------------------

  Scenario: Strategize proceeds when tier_service is None (no hydration attempted)
    Given a mock PlanExecutor without tier_service
    And a plan in the Strategize phase
    When I call run_strategize on that PlanExecutor
    Then hydrate_tiers_for_plan should not have been called
    And the plan executor strategize result should be a valid run_strategize response
