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