Feature: CorrectionService full coverage
  As a developer maintaining CorrectionService
  I want every line and branch fully tested
  So that correction_service.py achieves 100% coverage

  Background:
    Given a coverage test correction service

  # -------------------------------------------------------------------
  # __init__
  # -------------------------------------------------------------------

  Scenario: Service initializes with empty internal dictionaries
    Then the coverage service corrections dict should be empty
    And the coverage service impacts dict should be empty
    And the coverage service attempts dict should be empty
    And the coverage service results dict should be empty

  # -------------------------------------------------------------------
  # request_correction – happy paths
  # -------------------------------------------------------------------

  Scenario: Create a revert correction with defaults
    When I cov-request a correction for plan "P1" targeting "D1" in revert mode
    Then the cov-request should be stored in the service
    And the cov-request plan_id should be "P1"
    And the cov-request target_decision_id should be "D1"
    And the cov-request mode should be "revert"
    And the cov-request status should be "pending"
    And the cov-request dry_run should be false
    And the cov-request guidance should be empty

  Scenario: Create an append correction with guidance and dry_run
    When I cov-request a correction for plan "P2" targeting "D2" in append mode with guidance "fix things" and dry_run
    Then the cov-request should be stored in the service
    And the cov-request plan_id should be "P2"
    And the cov-request target_decision_id should be "D2"
    And the cov-request mode should be "append"
    And the cov-request dry_run should be true
    And the cov-request guidance should be "fix things"

  # -------------------------------------------------------------------
  # request_correction – validation errors
  # -------------------------------------------------------------------

  Scenario: Empty plan_id raises ValidationError
    When I cov-attempt to create a correction with empty plan_id and target "D1"
    Then a cov ValidationError should have been raised

  Scenario: Whitespace-only plan_id raises ValidationError
    When I cov-attempt to create a correction with plan_id "   " and target "D1"
    Then a cov ValidationError should have been raised

  Scenario: Empty target_decision_id raises ValidationError
    When I cov-attempt to create a correction with plan_id "P1" and empty target
    Then a cov ValidationError should have been raised

  Scenario: Whitespace-only target_decision_id raises ValidationError
    When I cov-attempt to create a correction with plan_id "P1" and target "   "
    Then a cov ValidationError should have been raised

  # -------------------------------------------------------------------
  # analyze_impact – BFS traversal
  # -------------------------------------------------------------------

  Scenario: Analyze impact with no decision tree yields single-node result
    Given a cov-stored revert correction for plan "P1" targeting "ROOT"
    When I cov-analyze impact with an empty tree
    Then the cov-impact affected decisions should be "ROOT"
    And the cov-impact risk level should be "low"
    And the cov-impact rollback tier should be "full"
    And the cov-impact estimated cost should be 1.5
    And the cov-impact artifacts to archive should be "ROOT.artifact"
    And the cov-impact affected files should be "ROOT.py"

  Scenario: Analyze impact with tree having children
    Given a cov-stored revert correction for plan "P1" targeting "A"
    When I cov-analyze impact with adjacency "A->B,C;B->D"
    Then the cov-impact affected decisions should be "A,B,C,D"
    And the cov-impact risk level should be "medium"
    And the cov-impact estimated cost should be 6.0
    And the cov-impact affected decisions count should be 4

  Scenario: Analyze impact for append mode sets rollback tier to append_only
    Given a cov-stored append correction for plan "P1" targeting "X"
    When I cov-analyze impact with an empty tree
    Then the cov-impact rollback tier should be "append_only"

  Scenario: Analyze impact for nonexistent correction raises ResourceNotFoundError
    When I cov-attempt to analyze impact for correction id "BOGUS_ID"
    Then a cov ResourceNotFoundError should have been raised

  Scenario: Analyze impact sets status to analyzing
    Given a cov-stored revert correction for plan "P1" targeting "N1"
    When I cov-analyze impact with an empty tree
    Then the cov-stored correction status should be "analyzing"

  # -------------------------------------------------------------------
  # generate_dry_run_report
  # -------------------------------------------------------------------

  Scenario: Dry-run report for low-risk revert with single decision
    Given a cov-stored revert correction for plan "P1" targeting "SOLO"
    When I cov-generate dry-run report with an empty tree
    Then the cov dry-run mode should be "revert"
    And the cov dry-run warnings should be empty
    And the cov dry-run decisions to invalidate should be "SOLO"
    And the cov dry-run estimated recompute time should be 2.0

  Scenario: Dry-run report for medium-risk revert with multiple decisions
    Given a cov-stored revert correction for plan "P1" targeting "R"
    When I cov-generate dry-run report with adjacency "R->C1,C2,C3,C4"
    Then the cov dry-run warnings should contain "Medium risk"
    And the cov dry-run warnings should contain "Revert will invalidate 5 decisions"
    And the cov dry-run decisions to invalidate count should be 5
    And the cov dry-run estimated recompute time should be 10.0

  Scenario: Dry-run report for high-risk revert
    Given a cov-stored revert correction for plan "P1" targeting "H"
    When I cov-generate dry-run report with a chain of 12 nodes rooted at "H"
    Then the cov dry-run warnings should contain "High risk"
    And the cov dry-run warnings should contain "Revert will invalidate 12 decisions"
    And the cov dry-run decisions to invalidate count should be 12

  Scenario: Dry-run report for append mode has empty decisions_to_invalidate
    Given a cov-stored append correction for plan "P1" targeting "APP"
    When I cov-generate dry-run report with an empty tree
    Then the cov dry-run mode should be "append"
    And the cov dry-run decisions to invalidate should be empty list
    And the cov dry-run warnings should be empty

  Scenario: Dry-run report for nonexistent correction raises error
    When I cov-attempt to generate dry-run report for correction id "NO_SUCH"
    Then a cov ResourceNotFoundError should have been raised

  # -------------------------------------------------------------------
  # execute_revert
  # -------------------------------------------------------------------

  Scenario: Execute revert on a pending correction succeeds
    Given a cov-stored revert correction for plan "P1" targeting "T1"
    When I cov-execute revert with adjacency "T1->T2"
    Then the cov revert result status should be "applied"
    And the cov revert result reverted decisions should include "T1"
    And the cov revert result reverted decisions should include "T2"
    And the cov revert result archived artifacts should include "T1.artifact"
    And the cov revert result archived artifacts should include "T2.artifact"
    And the cov-stored correction status should be "applied"
    And the cov attempts for the stored correction should have 1 entry
    And the cov first attempt should be successful
    And the cov first attempt completed_at should be set

  Scenario: Execute revert with empty tree marks only the target
    Given a cov-stored revert correction for plan "P1" targeting "ONLY"
    When I cov-execute revert with empty tree
    Then the cov revert result status should be "applied"
    And the cov revert result reverted decisions should include "ONLY"

  Scenario: Execute revert on already-applied correction raises ValidationError
    Given a cov-stored revert correction for plan "P1" targeting "R1"
    And the cov-stored correction has been executed via revert with empty tree
    When I cov-attempt to execute revert on the stored correction
    Then a cov ValidationError should have been raised

  # -------------------------------------------------------------------
  # execute_append
  # -------------------------------------------------------------------

  Scenario: Execute append on a pending correction succeeds
    Given a cov-stored append correction for plan "P1" targeting "A1"
    When I cov-execute append for the stored correction
    Then the cov append result status should be "applied"
    And the cov append result spawned_child_plan_id should not be none
    And the cov append result new_decisions should not be empty
    And the cov-stored correction status should be "applied"
    And the cov attempts for the stored correction should have 1 entry
    And the cov first attempt should be successful
    And the cov first attempt details should contain spawned_child_plan_id

  Scenario: Execute append on already-applied correction raises ValidationError
    Given a cov-stored append correction for plan "P1" targeting "A2"
    And the cov-stored correction has been executed via append
    When I cov-attempt to execute append on the stored correction
    Then a cov ValidationError should have been raised

  # -------------------------------------------------------------------
  # execute_correction (dispatch)
  # -------------------------------------------------------------------

  Scenario: Dispatch routes revert mode to execute_revert
    Given a cov-stored revert correction for plan "P1" targeting "DR"
    When I cov-dispatch execute correction with adjacency "DR->DR2"
    Then the cov dispatch result status should be "applied"
    And the cov dispatch result reverted decisions should include "DR"
    And the cov dispatch result reverted decisions should include "DR2"

  Scenario: Dispatch routes append mode to execute_append
    Given a cov-stored append correction for plan "P1" targeting "DA"
    When I cov-dispatch execute correction with no tree
    Then the cov dispatch result status should be "applied"
    And the cov dispatch result spawned_child_plan_id should not be none

  # -------------------------------------------------------------------
  # get_correction
  # -------------------------------------------------------------------

  Scenario: Get correction by id returns correct request
    Given a cov-stored revert correction for plan "PG" targeting "DG"
    When I cov-get the stored correction by id
    Then the cov-retrieved correction plan_id should be "PG"
    And the cov-retrieved correction target_decision_id should be "DG"

  Scenario: Get correction for nonexistent id raises ResourceNotFoundError
    When I cov-attempt to get correction with id "MISSING"
    Then a cov ResourceNotFoundError should have been raised

  # -------------------------------------------------------------------
  # list_corrections
  # -------------------------------------------------------------------

  Scenario: List all corrections without filter
    Given a cov-stored revert correction for plan "PA" targeting "DA"
    And a cov-stored revert correction for plan "PB" targeting "DB"
    When I cov-list all corrections without filter
    Then the cov corrections list should have at least 2 items

  Scenario: List corrections filtered by plan_id
    Given a cov-stored revert correction for plan "PX" targeting "DX"
    Given a cov-stored append correction for plan "PY" targeting "DY"
    When I cov-list corrections for plan "PX"
    Then the cov corrections list should have 1 item

  Scenario: List corrections filtered by plan_id with no matches
    When I cov-list corrections for plan "NONEXISTENT_PLAN"
    Then the cov corrections list should have 0 items

  # -------------------------------------------------------------------
  # list_attempts
  # -------------------------------------------------------------------

  Scenario: List attempts before any execution returns empty
    Given a cov-stored revert correction for plan "P1" targeting "D1"
    When I cov-list attempts for the stored correction
    Then the cov attempts list should have 0 items

  Scenario: List attempts after execution returns the attempt
    Given a cov-stored revert correction for plan "P1" targeting "D1"
    And the cov-stored correction has been executed via revert with empty tree
    When I cov-list attempts for the stored correction
    Then the cov attempts list should have 1 item

  Scenario: List attempts for nonexistent correction raises error
    When I cov-attempt to list attempts for correction id "NOPE"
    Then a cov ResourceNotFoundError should have been raised

  # -------------------------------------------------------------------
  # cancel_correction
  # -------------------------------------------------------------------

  Scenario: Cancel a pending correction succeeds
    Given a cov-stored revert correction for plan "P1" targeting "D1"
    When I cov-cancel the stored correction
    Then the cov-stored correction status should be "cancelled"

  Scenario: Cancel an analyzing correction succeeds
    Given a cov-stored revert correction for plan "P1" targeting "D1"
    And the cov-stored correction has been analyzed with empty tree
    When I cov-cancel the stored correction
    Then the cov-stored correction status should be "cancelled"

  Scenario: Cancel an already-applied correction raises ValidationError
    Given a cov-stored revert correction for plan "P1" targeting "D1"
    And the cov-stored correction has been executed via revert with empty tree
    When I cov-attempt to cancel the stored correction
    Then a cov ValidationError should have been raised

  Scenario: Cancel an already-cancelled correction raises ValidationError
    Given a cov-stored revert correction for plan "P1" targeting "D1"
    When I cov-cancel the stored correction
    And I cov-attempt to cancel the stored correction
    Then a cov ValidationError should have been raised

  # -------------------------------------------------------------------
  # _classify_risk (static)
  # -------------------------------------------------------------------

  Scenario Outline: Risk classification boundary values
    Then cov classifying risk for <count> affected returns "<expected>"

    Examples:
      | count | expected |
      | 0     | low      |
      | 1     | low      |
      | 3     | low      |
      | 4     | medium   |
      | 10    | medium   |
      | 11    | high     |
      | 50    | high     |

  # -------------------------------------------------------------------
  # _compute_affected_subtree (static)
  # -------------------------------------------------------------------

  Scenario: Compute affected subtree with empty tree returns only root
    When I cov-compute subtree for "ROOT" with empty tree
    Then the cov subtree should be "ROOT"

  Scenario: Compute affected subtree with linear chain
    When I cov-compute subtree for "A" with adjacency "A->B;B->C;C->D"
    Then the cov subtree should be "A,B,C,D"
    And the cov subtree count should be 4

  Scenario: Compute affected subtree with branching tree
    When I cov-compute subtree for "R" with adjacency "R->L,M;L->LL,LR"
    Then the cov subtree should be "R,L,M,LL,LR"

  Scenario: Compute affected subtree starting at leaf node
    When I cov-compute subtree for "LEAF" with adjacency "ROOT->LEAF"
    Then the cov subtree should be "LEAF"
    And the cov subtree count should be 1

  # -------------------------------------------------------------------
  # _assert_executable internal helper (via execute_revert / execute_append)
  # -------------------------------------------------------------------

  Scenario: Execute revert on FAILED correction raises ValidationError
    Given a cov-stored revert correction for plan "P1" targeting "F1"
    And the cov-stored correction status is forced to "failed"
    When I cov-attempt to execute revert on the stored correction
    Then a cov ValidationError should have been raised

  Scenario: Execute append on EXECUTING correction raises ValidationError
    Given a cov-stored append correction for plan "P1" targeting "E1"
    And the cov-stored correction status is forced to "executing"
    When I cov-attempt to execute append on the stored correction
    Then a cov ValidationError should have been raised

  Scenario: Execute append on CANCELLED correction raises ValidationError
    Given a cov-stored append correction for plan "P1" targeting "C1"
    And the cov-stored correction status is forced to "cancelled"
    When I cov-attempt to execute append on the stored correction
    Then a cov ValidationError should have been raised
