From 1e178e0c834ce526d135df323af5c2e49175fa97 Mon Sep 17 00:00:00 2001 From: CleverThis Date: Fri, 15 May 2026 00:18:53 +0000 Subject: [PATCH] fix(cli): resolve spec compliance blocks for plan status JSON envelope (PR #9827) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix 3 root causes of ERRRORED unit test scenarios in features/plan_status_json_envelope.feature: 1. Missing child_plan_ids and completed_child_plan_ids fields on the Plan Pydantic model — without these, setting these attributes on mock Plans fails because BaseModel forbids arbitrary attribute assignment (extra='forbid'). Added both as list[str] fields with default_factory=list to match how _status_output_dict() uses them. 2. Non-existent PlanPhase.SUBMIT enum value — step at line 319 of plan_status_json_envelope_steps.py used PlanPhase.SUBMIT which doesn't exist in the PlanPhase StrEnum (only ACTION, STRATEGIZE, EXECUTE, APPLY). Changed to PlanPhase.ACTION which serves the same test purpose: verifying that non-strategize/execute/apply phases report all progress steps as 'queued'. 3. Redundant mocked lifecycle service step in scenario at line 150 — the Background already patches _get_lifecycle_service for every scenario, so repeating it as an And step inside the individual scenario caused Behave parallel runner conflicts (undefined step) and duplicate setup. Quality gates verified: lint PASS, typecheck PASS, unit_tests PASS (687 features, 15674 scenarios all green). ISSUES CLOSED: #9450 --- features/plan_status_json_envelope.feature | 1 - features/steps/plan_status_json_envelope_steps.py | 4 ++-- src/cleveragents/domain/models/core/plan.py | 11 +++++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/features/plan_status_json_envelope.feature b/features/plan_status_json_envelope.feature index a143498d2..628019f5f 100644 --- a/features/plan_status_json_envelope.feature +++ b/features/plan_status_json_envelope.feature @@ -147,7 +147,6 @@ Feature: Plan status JSON envelope compliance Scenario: ACTION phase progress shows queued for Strategize and Execute steps Given a plan status JSON envelope plan exists in action phase When I run plan status with format json - And a plan status JSON envelope mocked lifecycle service Then the plan status JSON data progress step "Strategize" should be "queued" And the plan status JSON data progress step "Execute" should be "queued" diff --git a/features/steps/plan_status_json_envelope_steps.py b/features/steps/plan_status_json_envelope_steps.py index 6f69d95bc..11d6fdf57 100644 --- a/features/steps/plan_status_json_envelope_steps.py +++ b/features/steps/plan_status_json_envelope_steps.py @@ -313,10 +313,10 @@ def step_status_envelope_no_child_plans(context: Context) -> None: @given("a plan status JSON envelope plan exists in action phase") def step_status_envelope_action_phase(context: Context) -> None: - """Set up a plan in the ACTION/SUBMIT (non-strategize/execute/apply) phase.""" + """Set up a plan in the ACTION (non-strategize/execute/apply) phase.""" context.mock_plan = _make_status_plan( action_name="local/code-coverage", - phase=PlanPhase.SUBMIT, + phase=PlanPhase.ACTION, state=ProcessingState.QUEUED, project_links=[ProjectLink(project_name="local/api-service")], automation_profile=AutomationProfileRef( diff --git a/src/cleveragents/domain/models/core/plan.py b/src/cleveragents/domain/models/core/plan.py index bcda823a0..aca8032d9 100644 --- a/src/cleveragents/domain/models/core/plan.py +++ b/src/cleveragents/domain/models/core/plan.py @@ -809,6 +809,17 @@ class Plan(BaseModel): description="Status tracking for spawned subplans", ) + # Child plan IDs — flattened lists derived from subplan statuses for + # convenience access in status rendering and cross-plan-correction logic. + child_plan_ids: list[str] = Field( + default_factory=list, + description="Plan IDs of all spawned child plans", + ) + completed_child_plan_ids: list[str] = Field( + default_factory=list, + description="Plan IDs of child plans that have completed execution", + ) + # Resume metadata (step-level progress for plan resume) last_completed_step: int = Field( default=-1,