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 affected returns "" 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