Feature: Consolidated Decision
  Combined scenarios from: decision_model, decision_persistence_serialization

  # ============================================================
  # Originally from: decision_model.feature
  # Feature: Decision domain model
  # ============================================================

  Scenario: All 11 decision types are defined
    Then the DecisionType enum should have exactly 11 members


  Scenario: Strategize-phase types are correctly classified
    Then STRATEGIZE_TYPES should contain "prompt_definition"
    And STRATEGIZE_TYPES should contain "invariant_enforced"
    And STRATEGIZE_TYPES should contain "strategy_choice"
    And STRATEGIZE_TYPES should contain "resource_selection"
    And STRATEGIZE_TYPES should contain "subplan_spawn"
    And STRATEGIZE_TYPES should contain "subplan_parallel_spawn"
    And STRATEGIZE_TYPES should contain "user_intervention"
    And STRATEGIZE_TYPES should have exactly 7 members


  Scenario: Execute-phase types are correctly classified
    Then EXECUTE_TYPES should contain "implementation_choice"
    And EXECUTE_TYPES should contain "resource_selection"
    And EXECUTE_TYPES should contain "tool_invocation"
    And EXECUTE_TYPES should contain "error_recovery"
    And EXECUTE_TYPES should contain "validation_response"
    And EXECUTE_TYPES should contain "subplan_spawn"
    And EXECUTE_TYPES should contain "subplan_parallel_spawn"
    And EXECUTE_TYPES should contain "user_intervention"
    And EXECUTE_TYPES should have exactly 8 members


  Scenario: user_intervention is a phase-agnostic type in both sets
    Then STRATEGIZE_TYPES should contain "user_intervention"
    And EXECUTE_TYPES should contain "user_intervention"

    # ------------------------------------------------------------------
    # Decision creation and ULID validation
    # ------------------------------------------------------------------


  Scenario: Create a minimal root decision
    Given a valid plan ULID
    When I create a prompt_definition decision with sequence 0
    Then the decision should be created successfully
    And the decision should be a root decision
    And the decision should have a valid ULID as decision_id
    And the decision type should be "prompt_definition"
    And the decision is_strategize_type should be true
    And the decision is_any_phase_type should be false


  Scenario: Create a non-root decision with parent
    Given a valid plan ULID
    And a valid parent decision ULID
    When I create a strategy_choice decision with sequence 1 and a parent
    Then the decision should be created successfully
    And the decision should not be a root decision
    And the decision is_strategize_type should be true


  Scenario: Create an execute-phase decision
    Given a valid plan ULID
    And a valid parent decision ULID
    When I create an implementation_choice decision with sequence 2 and a parent
    Then the decision should be created successfully
    And the decision is_execute_type should be true
    And the decision is_strategize_type should be false


  Scenario: user_intervention is valid in any phase
    Given a valid plan ULID
    When I create a user_intervention decision with sequence 3
    Then the decision should be created successfully
    And the decision is_any_phase_type should be true


  Scenario Outline: All dual-phase types report is_any_phase_type true
    Given a valid plan ULID
    And a valid parent decision ULID
    When I create a "<decision_type>" decision with sequence 4 and a parent
    Then the decision should be created successfully
    And the decision is_any_phase_type should be true

    Examples:
      | decision_type          |
      | resource_selection     |
      | subplan_spawn          |
      | subplan_parallel_spawn |
      | user_intervention      |


  Scenario Outline: Single-phase types report is_any_phase_type false
    Given a valid plan ULID
    And a valid parent decision ULID
    When I create a "<decision_type>" decision with sequence 5 and a parent
    Then the decision should be created successfully
    And the decision is_any_phase_type should be false

    Examples:
      | decision_type         |
      | invariant_enforced    |
      | strategy_choice       |
      | implementation_choice |
      | tool_invocation       |
      | error_recovery        |
      | validation_response   |


  Scenario: Invalid plan_id is rejected
    When I try to create a decision with plan_id "not-a-ulid"
    Then a decision validation error should be raised
    And the decision error should mention "plan_id"


  Scenario: Invalid parent_decision_id is rejected
    Given a valid plan ULID
    When I try to create a decision with parent_decision_id "bad-id"
    Then a decision validation error should be raised
    And the decision error should mention "parent_decision_id"

    # ------------------------------------------------------------------
    # prompt_definition root constraint
    # ------------------------------------------------------------------


  Scenario: prompt_definition with a parent is rejected
    Given a valid plan ULID
    And a valid parent decision ULID
    When I try to create a prompt_definition with a parent
    Then a decision validation error should be raised
    And the decision error should mention "root"

    # ------------------------------------------------------------------
    # Confidence score validation
    # ------------------------------------------------------------------


  Scenario: Confidence score within valid range
    Given a valid plan ULID
    When I create a decision with confidence score 0.85
    Then the decision should be created successfully
    And the decision confidence score should be 0.85


  Scenario: Confidence score of 0.0 is valid
    Given a valid plan ULID
    When I create a decision with confidence score 0.0
    Then the decision should be created successfully


  Scenario: Confidence score of 1.0 is valid
    Given a valid plan ULID
    When I create a decision with confidence score 1.0
    Then the decision should be created successfully


  Scenario: Confidence score above 1.0 is rejected
    Given a valid plan ULID
    When I try to create a decision with confidence score 1.5
    Then a decision validation error should be raised


  Scenario: Confidence score below 0.0 is rejected
    Given a valid plan ULID
    When I try to create a decision with confidence score -0.1
    Then a decision validation error should be raised


  Scenario: Confidence score of None is valid
    Given a valid plan ULID
    When I create a decision with confidence score None
    Then the decision should be created successfully
    And the decision confidence score should be None

    # ------------------------------------------------------------------
    # Correction metadata
    # ------------------------------------------------------------------


  Scenario: Create a correction decision
    Given a valid plan ULID
    And a valid corrected decision ULID
    When I create a correction decision
    Then the decision should be created successfully
    And the decision is_correction should be true


  Scenario: is_correction without corrects_decision_id is rejected
    Given a valid plan ULID
    When I try to create a decision with is_correction true but no corrects_decision_id
    Then a decision validation error should be raised
    And the decision error should mention "corrects_decision_id"


  Scenario: corrects_decision_id without is_correction is rejected
    Given a valid plan ULID
    And a valid corrected decision ULID
    When I try to create a decision with corrects_decision_id but is_correction false
    Then a decision validation error should be raised
    And the decision error should mention "is_correction"


  Scenario: superseded_by marks decision as superseded
    Given a valid plan ULID
    When I create a decision that is superseded
    Then the decision is_superseded should be true


  Scenario: Invalid superseded_by ULID is rejected
    Given a valid plan ULID
    When I try to create a decision with superseded_by "invalid"
    Then a decision validation error should be raised
    And the decision error should mention "superseded_by"


  Scenario: Invalid corrects_decision_id ULID is rejected
    Given a valid plan ULID
    When I try to create a decision with corrects_decision_id ULID "not-valid"
    Then a decision validation error should be raised
    And the decision error should mention "corrects_decision_id"


  Scenario: with_superseded_by returns a new superseded copy
    Given a valid plan ULID
    When I create a prompt_definition decision with sequence 0
    And I call with_superseded_by on the decision
    Then the original decision should not be superseded
    And the superseded copy should be superseded

    # ------------------------------------------------------------------
    # ContextSnapshot
    # ------------------------------------------------------------------


  Scenario: Create a decision with a populated context snapshot
    Given a valid plan ULID
    And a context snapshot with hash and resources
    When I create a decision with the context snapshot
    Then the decision should be created successfully
    And the decision context snapshot hash should not be empty
    And the decision context snapshot should have resources


  Scenario: Default context snapshot is empty
    Given a valid plan ULID
    When I create a prompt_definition decision with sequence 0
    Then the decision context snapshot hash should be empty

    # ------------------------------------------------------------------
    # ResourceRef and ArtifactRef
    # ------------------------------------------------------------------


  Scenario: ResourceRef requires non-empty resource_id
    When I try to create a ResourceRef with empty resource_id
    Then a decision validation error should be raised


  Scenario: ArtifactRef requires non-empty artifact_path
    When I try to create an ArtifactRef with empty artifact_path
    Then a decision validation error should be raised


  Scenario: Decision with artifacts_produced
    Given a valid plan ULID
    When I create a decision with artifacts
    Then the decision should have 2 artifacts produced

    # ------------------------------------------------------------------
    # Serialization
    # ------------------------------------------------------------------


  Scenario: Decision round-trips through dict serialization
    Given a valid plan ULID
    When I create a fully populated decision
    Then the decision should round-trip through model_dump and model_validate


  Scenario: as_cli_dict returns expected keys
    Given a valid plan ULID
    When I create a prompt_definition decision with sequence 0
    Then as_cli_dict should contain key "decision_id"
    And as_cli_dict should contain key "type"
    And as_cli_dict should contain key "confidence"
    And as_cli_dict should contain key "parent"

    # ------------------------------------------------------------------
    # All 11 decision types can be instantiated
    # ------------------------------------------------------------------


  Scenario Outline: Each decision type can be instantiated
    Given a valid plan ULID
    When I create a decision of type "<dtype>"
    Then the decision should be created successfully

    Examples:
      | dtype                  |
      | prompt_definition      |
      | invariant_enforced     |
      | strategy_choice        |
      | implementation_choice  |
      | resource_selection     |
      | subplan_spawn          |
      | subplan_parallel_spawn |
      | tool_invocation        |
      | error_recovery         |
      | validation_response    |
      | user_intervention      |


  # ============================================================
  # Originally from: decision_persistence_serialization.feature
  # Feature: Decision persistence via serialization round-trips
  # ============================================================

  Scenario: Persist a root decision through model_dump round-trip
    Given a decision persistence plan ULID
    When I decision persistence create a root prompt_definition with sequence 0
    And I decision persistence round-trip the decision through model_dump
    Then the decision persistence restored decision should match the original


  Scenario: Persist a child decision with all fields populated
    Given a decision persistence plan ULID
    And a decision persistence parent ULID
    When I decision persistence create a full strategy_choice child at sequence 1
    And I decision persistence round-trip the decision through model_dump
    Then the decision persistence restored decision should match the original
    And the decision persistence restored alternatives should have 3 entries


  Scenario: Persist an execute-phase decision with snapshot
    Given a decision persistence plan ULID
    And a decision persistence parent ULID
    And a decision persistence context snapshot with 2 resources
    When I decision persistence create an implementation_choice with the snapshot
    And I decision persistence round-trip the decision through model_dump
    Then the decision persistence restored snapshot hash should match
    And the decision persistence restored snapshot should have 2 resources

    # ------------------------------------------------------------------
    # JSON serialization round-trips
    # ------------------------------------------------------------------


  Scenario: Decision survives JSON serialization round-trip
    Given a decision persistence plan ULID
    When I decision persistence create a root prompt_definition with sequence 0
    And I decision persistence round-trip the decision through JSON
    Then the decision persistence restored decision should match the original


  Scenario: Full decision with artifacts survives JSON round-trip
    Given a decision persistence plan ULID
    And a decision persistence parent ULID
    When I decision persistence create a decision with 3 artifacts
    And I decision persistence round-trip the decision through JSON
    Then the decision persistence restored decision should have 3 artifacts

    # ------------------------------------------------------------------
    # Snapshot persistence
    # ------------------------------------------------------------------


  Scenario: Empty context snapshot persists correctly
    Given a decision persistence plan ULID
    When I decision persistence create a root prompt_definition with sequence 0
    And I decision persistence round-trip the decision through model_dump
    Then the decision persistence restored snapshot hash should be empty
    And the decision persistence restored snapshot should have 0 resources


  Scenario: Context snapshot with actor state ref persists
    Given a decision persistence plan ULID
    And a decision persistence parent ULID
    And a decision persistence snapshot with actor state ref "checkpoint://actor/42"
    When I decision persistence create a strategy_choice with the snapshot
    And I decision persistence round-trip the decision through model_dump
    Then the decision persistence restored actor state ref should be "checkpoint://actor/42"

    # ------------------------------------------------------------------
    # Correction chain persistence
    # ------------------------------------------------------------------


  Scenario: Correction decision persists correction metadata
    Given a decision persistence plan ULID
    And a decision persistence corrected decision ULID
    When I decision persistence create a correction decision
    And I decision persistence round-trip the decision through model_dump
    Then the decision persistence restored is_correction should be true
    And the decision persistence restored corrects_decision_id should match


  Scenario: Superseded decision persists superseded_by
    Given a decision persistence plan ULID
    When I decision persistence create a decision superseded by another
    And I decision persistence round-trip the decision through model_dump
    Then the decision persistence restored is_superseded should be true


  Scenario: Correction chain of 3 decisions persists correctly
    Given a decision persistence plan ULID
    When I decision persistence build a correction chain of 3 decisions
    And I decision persistence round-trip all decisions through model_dump
    Then the decision persistence correction chain should be reconstructable

    # ------------------------------------------------------------------
    # Decision tree reconstruction
    # ------------------------------------------------------------------


  Scenario: Reconstruct a 3-level decision tree from serialized data
    Given a decision persistence plan ULID
    When I decision persistence build a 3-level decision tree
    And I decision persistence serialize and deserialize all tree nodes
    Then the decision persistence tree parent links should be intact
    And the decision persistence tree should have 7 nodes


  Scenario: Decision downstream_decision_ids survive round-trip
    Given a decision persistence plan ULID
    When I decision persistence create a decision with 4 downstream IDs
    And I decision persistence round-trip the decision through model_dump
    Then the decision persistence restored should have 4 downstream IDs


  Scenario: Decision downstream_plan_ids survive round-trip
    Given a decision persistence plan ULID
    When I decision persistence create a decision with 2 downstream plan IDs
    And I decision persistence round-trip the decision through model_dump
    Then the decision persistence restored should have 2 downstream plan IDs

    # ------------------------------------------------------------------
    # Edge cases
    # ------------------------------------------------------------------


  Scenario: Decision with empty alternatives list persists
    Given a decision persistence plan ULID
    When I decision persistence create a decision with no alternatives
    And I decision persistence round-trip the decision through model_dump
    Then the decision persistence restored alternatives should have 0 entries


  Scenario: Decision with max confidence 1.0 persists
    Given a decision persistence plan ULID
    When I decision persistence create a decision with confidence 1.0
    And I decision persistence round-trip the decision through model_dump
    Then the decision persistence restored confidence should be 1.0


  Scenario: Decision with min confidence 0.0 persists
    Given a decision persistence plan ULID
    When I decision persistence create a decision with confidence 0.0
    And I decision persistence round-trip the decision through model_dump
    Then the decision persistence restored confidence should be 0.0


  Scenario: Decision with None confidence persists
    Given a decision persistence plan ULID
    When I decision persistence create a decision with confidence None
    And I decision persistence round-trip the decision through model_dump
    Then the decision persistence restored confidence should be None


  Scenario: All decision types round-trip through model_dump
    Given a decision persistence plan ULID
    When I decision persistence create and round-trip all decision types
    Then all decision persistence round-trips should succeed


  Scenario: Decision with long rationale text persists
    Given a decision persistence plan ULID
    When I decision persistence create a decision with a 2000 character rationale
    And I decision persistence round-trip the decision through model_dump
    Then the decision persistence restored rationale length should be 2000
