272 lines
15 KiB
Gherkin
272 lines
15 KiB
Gherkin
@phase2 @correction @flows
|
|
Feature: Correction flows — revert and append
|
|
As an operator
|
|
I want to revert or append corrections to a plan's decision tree
|
|
So that I can fix mistakes without restarting from scratch
|
|
|
|
# ───────────────────────────────────────────────────────────
|
|
# Revert scenarios
|
|
# ───────────────────────────────────────────────────────────
|
|
|
|
Scenario: Simple revert invalidates target decision
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
And a decision tree where "D1" has no children
|
|
When I execute the revert correction
|
|
Then the correction flow result status should be "applied"
|
|
And the reverted decisions should contain "D1"
|
|
|
|
Scenario: Revert deep subtree invalidates all descendants
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
And a multi-parent decision tree with "D1" children "D2,D3" and "D2" children "D4,D5"
|
|
When I execute the revert correction
|
|
Then the reverted decisions should contain "D1"
|
|
And the reverted decisions should contain "D2"
|
|
And the reverted decisions should contain "D3"
|
|
And the reverted decisions should contain "D4"
|
|
And the reverted decisions should contain "D5"
|
|
|
|
Scenario: Revert archives artifacts for each affected decision
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
And a simple decision tree where "D1" has children "D2"
|
|
When I execute the revert correction
|
|
Then the archived artifacts should include "D1.artifact"
|
|
And the archived artifacts should include "D2.artifact"
|
|
|
|
Scenario: Revert correction transitions through expected statuses
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
Then the correction flow status should be "pending"
|
|
When I execute the revert correction with a decision tree where "D1" has no children
|
|
Then the correction flow status should be "applied"
|
|
|
|
# ───────────────────────────────────────────────────────────
|
|
# Append scenarios
|
|
# ───────────────────────────────────────────────────────────
|
|
|
|
Scenario: Simple append spawns child plan
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in append mode
|
|
When I execute the append correction
|
|
Then the correction flow result status should be "applied"
|
|
And the result should have a spawned child plan id
|
|
|
|
Scenario: Append with guidance preserves guidance on request
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in append mode with guidance "Fix auth module"
|
|
When I execute the append correction
|
|
Then the correction flow guidance should be "Fix auth module"
|
|
|
|
Scenario: Append creates new decision in result
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in append mode
|
|
When I execute the append correction
|
|
Then the result new decisions should not be empty
|
|
|
|
# ───────────────────────────────────────────────────────────
|
|
# Impact analysis
|
|
# ───────────────────────────────────────────────────────────
|
|
|
|
Scenario: Impact analysis with BFS subtree traversal
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
And a multi-parent decision tree with "D1" children "D2,D3" and "D3" children "D6"
|
|
When I analyze the impact
|
|
Then the affected decisions should be "D1,D2,D3,D6"
|
|
|
|
Scenario: Impact analysis risk level low for small subtree
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
And a simple decision tree where "D1" has children "D2"
|
|
When I analyze the impact
|
|
Then the risk level should be "low"
|
|
|
|
Scenario: Impact analysis risk level medium for moderate subtree
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
And a decision tree with 7 nodes rooted at "D1"
|
|
When I analyze the impact
|
|
Then the risk level should be "medium"
|
|
|
|
Scenario: Impact analysis risk level high for large subtree
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
And a decision tree with 15 nodes rooted at "D1"
|
|
When I analyze the impact
|
|
Then the risk level should be "high"
|
|
|
|
Scenario: Impact analysis on leaf node returns only the target
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "LEAF" in revert mode
|
|
And an empty decision tree
|
|
When I analyze the impact
|
|
Then the affected decisions should be "LEAF"
|
|
|
|
# ───────────────────────────────────────────────────────────
|
|
# Dry-run
|
|
# ───────────────────────────────────────────────────────────
|
|
|
|
Scenario: Dry-run report generation for revert
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
And a simple decision tree where "D1" has children "D2,D3"
|
|
When I generate a dry-run report
|
|
Then the report mode should be "revert"
|
|
And the report decisions to invalidate should contain "D1"
|
|
And the report estimated recompute time should be greater than 0
|
|
|
|
Scenario: Dry-run report generates warnings for high risk
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
And a decision tree with 15 nodes rooted at "D1"
|
|
When I generate a dry-run report
|
|
Then the report warnings should contain "High risk"
|
|
|
|
Scenario: Dry-run report generates warnings for medium risk
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
And a decision tree with 7 nodes rooted at "D1"
|
|
When I generate a dry-run report
|
|
Then the report warnings should contain "Medium risk"
|
|
|
|
Scenario: Dry-run report for append has no decisions to invalidate
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in append mode
|
|
When I generate a dry-run report
|
|
Then the report decisions to invalidate should be empty
|
|
|
|
# ───────────────────────────────────────────────────────────
|
|
# Error handling
|
|
# ───────────────────────────────────────────────────────────
|
|
|
|
Scenario: Get correction with invalid id raises not found
|
|
Given a correction flow service
|
|
When I try to get correction flow "nonexistent-id"
|
|
Then a correction flow resource not found error should be raised
|
|
|
|
Scenario: Execute already applied correction raises validation error
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
And I execute the revert correction with a decision tree where "D1" has no children
|
|
When I try to execute the revert correction again
|
|
Then a validation error should be raised for status
|
|
|
|
Scenario: Execute already cancelled correction raises validation error
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
And I cancel the correction flow
|
|
When I try to execute the revert correction again
|
|
Then a validation error should be raised for status
|
|
|
|
Scenario: Cancel already applied correction raises validation error
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
And I execute the revert correction with a decision tree where "D1" has no children
|
|
When I try to cancel the correction flow
|
|
Then a validation error should be raised for status
|
|
|
|
# ───────────────────────────────────────────────────────────
|
|
# Status transitions
|
|
# ───────────────────────────────────────────────────────────
|
|
|
|
Scenario: Correction status transitions from pending to applied on revert
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
When I execute the revert correction with a decision tree where "D1" has no children
|
|
Then the correction flow status should be "applied"
|
|
|
|
Scenario: Correction status transitions from pending to cancelled
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
When I cancel the correction flow
|
|
Then the correction flow status should be "cancelled"
|
|
|
|
# ───────────────────────────────────────────────────────────
|
|
# Multi-correction & listing
|
|
# ───────────────────────────────────────────────────────────
|
|
|
|
Scenario: Multiple corrections on same plan are listed correctly
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
And a correction request for plan "P1" targeting decision "D2" in append mode
|
|
When I list correction flows for plan "P1"
|
|
Then the correction list should have 2 items
|
|
|
|
Scenario: List corrections filters by plan id
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
And a correction request for plan "P2" targeting decision "D2" in append mode
|
|
When I list correction flows for plan "P1"
|
|
Then the correction list should have 1 items
|
|
|
|
# ───────────────────────────────────────────────────────────
|
|
# Cancellation
|
|
# ───────────────────────────────────────────────────────────
|
|
|
|
Scenario: Cancel pending correction succeeds
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
When I cancel the correction flow
|
|
Then the correction flow status should be "cancelled"
|
|
|
|
# ───────────────────────────────────────────────────────────
|
|
# Attempt tracking
|
|
# ───────────────────────────────────────────────────────────
|
|
|
|
Scenario: Execution records an attempt
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
When I execute the revert correction with a decision tree where "D1" has no children
|
|
Then the attempt list should have 1 entries
|
|
And the first attempt should be successful
|
|
|
|
Scenario: Append execution records an attempt
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in append mode
|
|
When I execute the append correction
|
|
Then the attempt list should have 1 entries
|
|
|
|
# ───────────────────────────────────────────────────────────
|
|
# Model validation
|
|
# ───────────────────────────────────────────────────────────
|
|
|
|
Scenario: CorrectionRequest rejects empty plan_id
|
|
Given a correction flow service
|
|
When I try to create a correction with empty plan_id
|
|
Then a validation error should be raised for empty field
|
|
|
|
Scenario: CorrectionRequest rejects empty target_decision_id
|
|
Given a correction flow service
|
|
When I try to create a correction with empty target_decision_id
|
|
Then a validation error should be raised for empty field
|
|
|
|
Scenario: CorrectionImpact rejects invalid risk level
|
|
When I try to create a correction impact with risk level "critical"
|
|
Then a correction flow pydantic validation error should be raised
|
|
|
|
Scenario: CorrectionDryRunReport contains all expected fields
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
And a simple decision tree where "D1" has children "D2"
|
|
When I generate a dry-run report
|
|
Then the report should have a correction_id
|
|
And the report should have an impact object
|
|
And the report should have a warnings list
|
|
|
|
Scenario: Execute correction dispatches to revert
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in revert mode
|
|
And a decision tree where "D1" has no children
|
|
When I execute correction via dispatch
|
|
Then the correction flow result status should be "applied"
|
|
And the reverted decisions should contain "D1"
|
|
|
|
Scenario: Execute correction dispatches to append
|
|
Given a correction flow service
|
|
And a correction request for plan "P1" targeting decision "D1" in append mode
|
|
When I execute correction via dispatch
|
|
Then the correction flow result status should be "applied"
|
|
And the result should have a spawned child plan id
|