Files
cleveragents-core/robot/plan_lifecycle_model_validation.robot
Luis Mendes 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
fix(domain): align plan lifecycle model validation with specification
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
2026-03-23 23:33:33 +00:00

75 lines
4.0 KiB
Plaintext

*** Settings ***
Documentation Integration tests for plan lifecycle model validation:
... ERRORED terminality, per-phase state constraints, and
... rejection of invalid phase/state combinations.
Resource ${CURDIR}/common.resource
Suite Setup Setup Test Environment
Suite Teardown Cleanup Test Environment
*** Variables ***
${HELPER_SCRIPT} robot/helper_plan_lifecycle_model_validation.py
*** Test Cases ***
ERRORED State Is Terminal
[Documentation] Verify that a plan with ERRORED processing state is terminal
[Tags] lifecycle plan model terminal
${result}= Run Process ${PYTHON} ${HELPER_SCRIPT} errored-is-terminal cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} errored-is-terminal-ok
APPLIED Only Valid In APPLY Phase
[Documentation] Verify APPLIED state is rejected outside the APPLY phase
[Tags] lifecycle plan model validation
${result}= Run Process ${PYTHON} ${HELPER_SCRIPT} applied-only-apply cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} applied-only-apply-ok
CONSTRAINED Only Valid In APPLY Phase
[Documentation] Verify CONSTRAINED state is rejected outside the APPLY phase
[Tags] lifecycle plan model validation
${result}= Run Process ${PYTHON} ${HELPER_SCRIPT} constrained-only-apply cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} constrained-only-apply-ok
COMPLETE Only Valid In STRATEGIZE Or EXECUTE
[Documentation] Verify COMPLETE state is rejected in APPLY and ACTION phases
[Tags] lifecycle plan model validation
${result}= Run Process ${PYTHON} ${HELPER_SCRIPT} complete-strategize-execute cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} complete-strategize-execute-ok
QUEUED Valid In Any Phase
[Documentation] Verify QUEUED state is accepted in all phases
[Tags] lifecycle plan model validation
${result}= Run Process ${PYTHON} ${HELPER_SCRIPT} queued-any-phase cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} queued-any-phase-ok
PROCESSING Valid In Any Phase
[Documentation] Verify PROCESSING state is accepted in all phases
[Tags] lifecycle plan model validation
${result}= Run Process ${PYTHON} ${HELPER_SCRIPT} processing-any-phase cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} processing-any-phase-ok
Assignment Order Safety
[Documentation] Verify state-first assignment order avoids validator errors
[Tags] lifecycle plan model validation regression
${result}= Run Process ${PYTHON} ${HELPER_SCRIPT} assignment-order-safety cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} assignment-order-safety-ok
Deserialization Coercion
[Documentation] Verify to_domain coerces legacy invalid phase/state combos
[Tags] lifecycle plan model validation deserialization
${result}= Run Process ${PYTHON} ${HELPER_SCRIPT} deserialization-coercion cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} deserialization-coercion-ok
Deserialization Coercion All Branches
[Documentation] Verify all three coercion branches in to_domain
[Tags] lifecycle plan model validation deserialization
${result}= Run Process ${PYTHON} ${HELPER_SCRIPT} deserialization-coercion-all-branches cwd=${WORKSPACE}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} deserialization-coercion-all-branches-ok