9e316b1a3e
CI / build (pull_request) Successful in 22s
CI / typecheck (pull_request) Successful in 47s
CI / lint (pull_request) Successful in 3m17s
CI / quality (pull_request) Successful in 3m33s
CI / security (pull_request) Successful in 3m59s
CI / unit_tests (pull_request) Successful in 5m31s
CI / docker (pull_request) Successful in 57s
CI / coverage (pull_request) Successful in 12m32s
CI / status-check (pull_request) Successful in 1s
CI / integration_tests (pull_request) Successful in 2m25s
CI / e2e_tests (pull_request) Successful in 7m9s
CI / benchmark-publish (pull_request) Has been skipped
CI / build (push) Successful in 26s
CI / lint (push) Successful in 3m18s
CI / typecheck (push) Successful in 3m54s
CI / security (push) Successful in 4m2s
CI / quality (push) Successful in 3m33s
CI / integration_tests (push) Successful in 5m47s
CI / unit_tests (push) Successful in 7m6s
CI / docker (push) Successful in 39s
CI / benchmark-regression (pull_request) Failing after 21m11s
CI / coverage (push) Failing after 19m3s
CI / benchmark-regression (push) Has been skipped
CI / e2e_tests (push) Failing after 21m14s
CI / status-check (push) Failing after 1s
CI / benchmark-publish (push) Failing after 18m51s
Aligned the plan lifecycle model with the specification: 1. ERRORED is now treated as terminal in is_terminal property, matching the spec table where errored is marked "Terminal? Yes" for all processing phases. 2. Added per-phase state validation via model_validator: APPLIED and CONSTRAINED are only valid in APPLY phase; COMPLETE is only valid in STRATEGIZE or EXECUTE phases. Invalid combinations now raise ValueError at construction time. 3. Updated ProcessingState.COMPLETE docstring to clarify phase-level terminality semantics. 4. Fixed assignment ordering in execute_plan() to set processing_state before phase, consistent with the state-first pattern used in apply_plan() and _perform_reversion(). 5. Added defensive coercion in LifecyclePlanModel.to_domain() to handle legacy DB rows with invalid phase/state combinations (e.g. APPLY/COMPLETE -> APPLY/APPLIED) with warning-level logging for observability. 6. Updated module docstrings: ERRORED description now reflects terminal semantics, terminal outcomes location clarified for all phases, can_revert_to docstring notes ERRORED/CONSTRAINED are terminal but revertable, is_terminal docstring explains the distinction between terminal and permanently irrecoverable and documents why COMPLETE is not plan-terminal despite the spec marking it "Terminal? Yes" (phase-level vs plan-level). 7. Updated PlanResumeService.validate_eligibility() docstring to reflect that ERRORED is now terminal but still eligible for resume. 8. Added CHANGELOG entry. ISSUES CLOSED: #918
191 lines
8.9 KiB
Gherkin
191 lines
8.9 KiB
Gherkin
Feature: Plan lifecycle model validation
|
|
Verify that the plan lifecycle model enforces the specification
|
|
constraints: ERRORED terminality, per-phase state validation,
|
|
and rejection of invalid phase/state combinations.
|
|
|
|
# ---------------------------------------------------------------
|
|
# ERRORED is terminal (spec alignment)
|
|
# ---------------------------------------------------------------
|
|
|
|
Scenario: ERRORED state is terminal
|
|
Given a plmv plan in STRATEGIZE phase with ERRORED state
|
|
Then the plmv plan should be terminal
|
|
|
|
# ---------------------------------------------------------------
|
|
# APPLIED only valid in APPLY phase
|
|
# ---------------------------------------------------------------
|
|
|
|
Scenario: APPLIED only valid in APPLY phase
|
|
When I try to create a plmv plan with phase STRATEGIZE and state APPLIED
|
|
Then a plmv validation error should be raised containing "APPLIED is only valid in the APPLY phase"
|
|
|
|
# ---------------------------------------------------------------
|
|
# CONSTRAINED only valid in APPLY phase
|
|
# ---------------------------------------------------------------
|
|
|
|
Scenario: CONSTRAINED only valid in APPLY phase
|
|
When I try to create a plmv plan with phase EXECUTE and state CONSTRAINED
|
|
Then a plmv validation error should be raised containing "CONSTRAINED is only valid in the APPLY phase"
|
|
|
|
# ---------------------------------------------------------------
|
|
# COMPLETE only valid in STRATEGIZE or EXECUTE phases
|
|
# ---------------------------------------------------------------
|
|
|
|
Scenario: COMPLETE only valid in STRATEGIZE or EXECUTE phase
|
|
When I try to create a plmv plan with phase APPLY and state COMPLETE
|
|
Then a plmv validation error should be raised containing "COMPLETE is only valid in STRATEGIZE or EXECUTE"
|
|
|
|
# ---------------------------------------------------------------
|
|
# QUEUED valid in any phase
|
|
# ---------------------------------------------------------------
|
|
|
|
Scenario: QUEUED valid in any phase
|
|
Given a plmv plan in STRATEGIZE phase with QUEUED state
|
|
And a plmv plan in EXECUTE phase with QUEUED state
|
|
And a plmv plan in APPLY phase with QUEUED state
|
|
Then all plmv plans should be valid
|
|
|
|
# ---------------------------------------------------------------
|
|
# Additional coverage: valid combos
|
|
# ---------------------------------------------------------------
|
|
|
|
Scenario: APPLIED is valid in APPLY phase
|
|
Given a plmv plan in APPLY phase with APPLIED state
|
|
Then the plmv plan should be terminal
|
|
|
|
Scenario: CONSTRAINED is valid in APPLY phase
|
|
Given a plmv plan in APPLY phase with CONSTRAINED state
|
|
Then the plmv plan should be terminal
|
|
|
|
Scenario: COMPLETE is valid in STRATEGIZE phase
|
|
Given a plmv plan in STRATEGIZE phase with COMPLETE state
|
|
Then the plmv plan should not be terminal
|
|
|
|
Scenario: COMPLETE is valid in EXECUTE phase
|
|
Given a plmv plan in EXECUTE phase with COMPLETE state
|
|
Then the plmv plan should not be terminal
|
|
|
|
Scenario: ERRORED in APPLY phase is also terminal
|
|
Given a plmv plan in APPLY phase with ERRORED state
|
|
Then the plmv plan should be terminal
|
|
|
|
Scenario: CANCELLED in EXECUTE phase is terminal
|
|
Given a plmv plan in EXECUTE phase with CANCELLED state
|
|
Then the plmv plan should be terminal
|
|
|
|
# ---------------------------------------------------------------
|
|
# Invalid combos for ACTION phase
|
|
# ---------------------------------------------------------------
|
|
|
|
Scenario: COMPLETE is not valid in ACTION phase
|
|
When I try to create a plmv plan with phase ACTION and state COMPLETE
|
|
Then a plmv validation error should be raised containing "COMPLETE is only valid in STRATEGIZE or EXECUTE"
|
|
|
|
Scenario: APPLIED is not valid in EXECUTE phase
|
|
When I try to create a plmv plan with phase EXECUTE and state APPLIED
|
|
Then a plmv validation error should be raised containing "APPLIED is only valid in the APPLY phase"
|
|
|
|
Scenario: APPLIED is not valid in ACTION phase
|
|
When I try to create a plmv plan with phase ACTION and state APPLIED
|
|
Then a plmv validation error should be raised containing "APPLIED is only valid in the APPLY phase"
|
|
|
|
Scenario: CONSTRAINED is not valid in ACTION phase
|
|
When I try to create a plmv plan with phase ACTION and state CONSTRAINED
|
|
Then a plmv validation error should be raised containing "CONSTRAINED is only valid in the APPLY phase"
|
|
|
|
Scenario: CONSTRAINED is not valid in STRATEGIZE phase
|
|
When I try to create a plmv plan with phase STRATEGIZE and state CONSTRAINED
|
|
Then a plmv validation error should be raised containing "CONSTRAINED is only valid in the APPLY phase"
|
|
|
|
# ---------------------------------------------------------------
|
|
# PROCESSING valid in any phase (T1)
|
|
# ---------------------------------------------------------------
|
|
|
|
Scenario: PROCESSING valid in any phase
|
|
Given a plmv plan in ACTION phase with PROCESSING state
|
|
And a plmv plan in STRATEGIZE phase with PROCESSING state
|
|
And a plmv plan in EXECUTE phase with PROCESSING state
|
|
And a plmv plan in APPLY phase with PROCESSING state
|
|
Then all plmv plans should be valid
|
|
|
|
# ---------------------------------------------------------------
|
|
# ERRORED valid in all phases including ACTION (T2)
|
|
# ---------------------------------------------------------------
|
|
|
|
Scenario: ERRORED in ACTION phase is terminal
|
|
Given a plmv plan in ACTION phase with ERRORED state
|
|
Then the plmv plan should be terminal
|
|
|
|
Scenario: ERRORED in EXECUTE phase is terminal
|
|
Given a plmv plan in EXECUTE phase with ERRORED state
|
|
Then the plmv plan should be terminal
|
|
|
|
# ---------------------------------------------------------------
|
|
# CANCELLED valid in all phases (additional)
|
|
# ---------------------------------------------------------------
|
|
|
|
Scenario: CANCELLED in ACTION phase is terminal
|
|
Given a plmv plan in ACTION phase with CANCELLED state
|
|
Then the plmv plan should be terminal
|
|
|
|
Scenario: CANCELLED in STRATEGIZE phase is terminal
|
|
Given a plmv plan in STRATEGIZE phase with CANCELLED state
|
|
Then the plmv plan should be terminal
|
|
|
|
Scenario: CANCELLED in APPLY phase is terminal
|
|
Given a plmv plan in APPLY phase with CANCELLED state
|
|
Then the plmv plan should be terminal
|
|
|
|
# ---------------------------------------------------------------
|
|
# Assignment-order regression: state-before-phase (T6)
|
|
# ---------------------------------------------------------------
|
|
|
|
Scenario: Phase transition with state-first assignment does not raise
|
|
Given a plmv plan in STRATEGIZE phase with COMPLETE state
|
|
When I plmv transition the plan to EXECUTE phase with QUEUED state using state-first order
|
|
Then the plmv plan should have phase EXECUTE and state QUEUED
|
|
|
|
# ---------------------------------------------------------------
|
|
# Assignment-order negative: phase-first with invalid intermediate
|
|
# ---------------------------------------------------------------
|
|
|
|
Scenario: Phase-first assignment with invalid intermediate state raises
|
|
Given a plmv plan in STRATEGIZE phase with COMPLETE state
|
|
When I plmv transition the plan to APPLY phase with APPLIED state using phase-first order
|
|
Then a plmv validation error should be raised containing "COMPLETE is only valid in STRATEGIZE or EXECUTE"
|
|
|
|
# ---------------------------------------------------------------
|
|
# ERRORED terminality blocks cancel, pause, resume (lifecycle)
|
|
# ---------------------------------------------------------------
|
|
|
|
Scenario: ERRORED plan cannot be cancelled because it is terminal
|
|
Given a plmv plan in EXECUTE phase with ERRORED state
|
|
Then the plmv plan should be terminal
|
|
And the plmv plan should not be cancellable
|
|
|
|
Scenario: ERRORED plan cannot be paused because it is terminal
|
|
Given a plmv plan in STRATEGIZE phase with ERRORED state
|
|
Then the plmv plan should be terminal
|
|
And the plmv plan should not be pausable
|
|
|
|
Scenario: ERRORED plan cannot be resumed via lifecycle because it is terminal
|
|
Given a plmv plan in EXECUTE phase with ERRORED state
|
|
Then the plmv plan should be terminal
|
|
And the plmv plan should not be resumable via lifecycle
|
|
|
|
# ---------------------------------------------------------------
|
|
# Deserialization coercion for legacy DB rows
|
|
# ---------------------------------------------------------------
|
|
|
|
Scenario: Legacy APPLY/COMPLETE is coerced to APPLY/APPLIED on deserialization
|
|
When I plmv deserialize a plan with phase "apply" and state "complete"
|
|
Then the plmv deserialized plan should have phase APPLY and state APPLIED
|
|
|
|
Scenario: Legacy STRATEGIZE/APPLIED is coerced to STRATEGIZE/ERRORED on deserialization
|
|
When I plmv deserialize a plan with phase "strategize" and state "applied"
|
|
Then the plmv deserialized plan should have phase STRATEGIZE and state ERRORED
|
|
|
|
Scenario: Legacy ACTION/COMPLETE is coerced to ACTION/QUEUED on deserialization
|
|
When I plmv deserialize a plan with phase "action" and state "complete"
|
|
Then the plmv deserialized plan should have phase ACTION and state QUEUED
|